• Codeforces Round #226 (Div. 2)


    A. Bear and Raspberry

    题意:找到相邻差值最大的差值。

    分析:水题,直接做。

    /****************************************
    * File Name: 226a.cpp
    * Author: sky0917
    * Created Time: 2014年01月24日 23:33:21
    ****************************************/
    #include <map>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 100005;
    
    int v[maxn];
    int main(){
        int n, m;
        int a, b, c;
        int x;
        while (scanf("%d %d",&n,&x)!=EOF){
            int ma = 0;
            int re = 0;
            for (int i=0; i<n; i++){
                scanf("%d",&v[i]);
            }       
            for (int i=1; i<n; i++){
                if (v[i-1] - v[i] > re){
                    re = v[i-1] - v[i];
                }
            }
            printf("%d
    ",max(0, re-x));
        }   
        return 0;
    }
    View Code

    B. Bear and Strings

    题意:给出一个字符串 s (1 ≤ |s| ≤ 5000),问这个字符串中有多少个子串中含有至少一个“bear”单词。

    分析:遍历一遍字符串,维护一个cnt,表示枚举的子串的开头位置的最左端

                 例如: acbeartbear

                 第一次发现 bear 之后,假如b的位置为 i ,那么:res += (i-cnt+1)*(len-i-3)

                 然后 cnt = i+1,这样就不会出现重复枚举的情况了。

    /****************************************
    * File Name: 226b.cpp
    * Author: sky0917
    * Created Time: 2014年01月24日 23:33:26
    ****************************************/
    #include <map>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 5005;
    
    char s[maxn];
    
    int main(){
        while (scanf("%s",&s)!=EOF){
            long long res = 0;
            long long len = strlen(s);
            long long cnt = 0;
            for (long long i=0; i<len-3; i++){
                if (s[i]=='b' && s[i+1]=='e' && s[i+2]=='a' && s[i+3]=='r'){
                    long long l = i-cnt+1;
                    long long r = len - i - 3;
                    res += l * r;
                    cnt = i+1;
                }   
            }
            printf("%I64d
    ",res);
        }
        return 0;
    }
    View Code

    C. Bear and Prime Numbers

    题意:  有 n (1 ≤ n ≤ 106) 个数,x1, x2, ..., xn (2 ≤ xi ≤ 107). 还有 m (1 ≤ m ≤ 50000) 个询问,每个询问为:l,r

                 表示要求出[l, r]区间中所有的质数 p 的 f (p) 之和,f (p) 表示n个数中能被p整除的数的个数。

    分析: 可以先打一个sqrt(1E7)范围的素数表,然后遍历一遍 n 个数,对每个数分解质因数,并用标记

                  数组标记,例如某个数有质因子 p,那么vis[p]++, 最后处理出一个sum[i] 数组,sum[i]表示vis[i]

                  数组中前 i 项的和,对于询问 l, r 输出 sum[r] - sum[l-1] 即可。

    /****************************************
    * File Name: 226c.cpp
    * Author: sky0917
    * Created Time: 2014年01月24日 23:33:45
    ****************************************/
    #include <map>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 1000005;
    
    int ma;
    int v[maxn*10];
    
    int vis[10003];
    int p[10004];
    int tp;
    void print(){
        tp = 0;
        for (int i=2; i<10000; i++){
            if (!vis[i]){
                p[tp++] = i;
                for (int j=i*2; j<10000; j+=i){
                    vis[j] = 1;
                }   
            }
        }   
    }   
    void cal(int x){
        for (int i=0; p[i]*p[i] <= x && i<tp; i++){
            if (x % p[i] == 0){
                v[p[i]]++;
                while (x % p[i] == 0){
                    x /= p[i];          
                }   
            }   
        }
        if (x != 1){
            v[x]++;
        }
    }
    
    int val[maxn];
    int sum[maxn*10];
    int main(){
        int n, m;
        int va;
        print();    
        while (scanf("%d",&n)!=EOF){
            ma = 0;
            for (int i=0; i<n; i++){
                scanf("%d",&val[i]);
                if (val[i] > ma)
                    ma = val[i];
            }
            for (int i=0; i<n; i++){
                cal(val[i]);    
            }   
            
            for (int i=1; i<=ma; i++){
                sum[i] = sum[i-1] + v[i];
            }
            scanf("%d",&m);
            int l, r;
            while (m--){
                scanf("%d %d",&l, &r);
                if (l > ma){
                    printf("0
    ");continue;
                }
                r = min(ma, r);
                printf("%d
    ",sum[r]-sum[l-1]); 
            }
        }   
        return 0;
    }
    View Code

    D. Bear and Floodlight

    题意: 有 n(n<20) 个灯,每个灯有一个自己可以照亮的角度di,现在某个人要从(l,0) 走到(r,0)的位置,需要一开始调整

             好灯的角度,使得这个人一路上都可以被灯照到,这个人走的路线是一条线段,问这个最多能走多远,当然最多不会超过

             r 位置。

    分析:状态压缩DP+向量旋转。

            dp[st] 表示在 s 状态下,最远走的位置,s中..001010.. 1表示用了那个灯,0表示没用,然后枚举没有用的灯,让其

            一开始的向量为(dp[st]-x0, -y0) 逆时针转 di 度得到新的向量,求出其和x轴的交点(x1,0) 

             那么dp[st|(1<<j)] = max(dp[st|(1<<j)], x1)

             最后输出dp[st] 和 r 的最小值 再减去 l 就好。

             注意一个情况,就是旋转过程中可能出现与x轴没有交点的情况,这个时候把 dp[st|(1<<j)] = r 就可以了。

    /****************************************
    * File Name: 226d.cpp
    * Author: sky0917
    * Created Time: 2014年01月25日  0:50:46
    ****************************************/
    #include <map>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const double p = acos(-1.0);
    double dp[1<<21];
    int n;
    double l, r;
    struct node{
        double x, y, di;
    }q[22];
    
    int main(){
        
        while (scanf("%d %lf %lf",&n,&l,&r)!=EOF){
        
            for (int i=0; i<n; i++){
                scanf("%lf %lf %lf",&q[i].x,&q[i].y,&q[i].di);
            }
    
            int st = 1<<n;
            for (int i=0; i<st; i++){
                dp[i] = -9999999.0;
            }   
            dp[0] = l;
            for (int i=0; i<st; i++){
                for (int j=0; j<n; j++){
                    if (((1<<j)&i) == 0){
                        int sta = i | (1<<j);   
                        double x = dp[i] - q[j].x;
                        double y = -q[j].y;
                        double a = x*cos(p*q[j].di/180)-y*sin(p*q[j].di/180);
                        double b = x*sin(p*q[j].di/180)+y*cos(p*q[j].di/180);
                        if (b >= 0){
                            dp[sta] = r;
                            continue;
                        }
                        double tmp = y*a/b+q[j].x;
                        dp[sta] = max(dp[sta], tmp);
                    }
                }
            }
            printf("%.10lf
    ",min(r, dp[st-1])-l);
        }   
        return 0;
    }
    View Code
  • 相关阅读:
    good array(数论+随机算法)
    triple balance(贪心+构造)
    树上拓扑排序(交互题)
    模数循环节
    string操作总结
    移除相邻(string操作+implement)
    二维树状数组(单点更新+区间查询)
    docker mysql Client does not support
    Docker 常见问题
    Linux安装 Docker
  • 原文地址:https://www.cnblogs.com/sky0917/p/3533204.html
Copyright © 2020-2023  润新知