• Codeforces Round #219 (Div. 2)


    A. Collecting Beats is Fun

    题意:给出一个矩阵,每个位置有个时间点,每个时间点最多只能按10个位置,问可不可满足每个时间点的位置都被按时按到。

    分析:直接模拟。

     1 /***************************************
     2 * File Name:219a.cpp
     3 * Author:`Wind
     4 * mail:809098085@qq.com
     5 * Created Time:2013年12月13日 22:00:51
     6 ***************************************/
     7 #include <map>
     8 #include <cmath>
     9 #include <queue>
    10 #include <string>
    11 #include <cstdio>
    12 #include <cstring>
    13 #include <algorithm>
    14 using namespace std;
    15 
    16 char g[6][6];
    17 int ti[11];
    18 int main(){
    19     int k;
    20     while (scanf("%d",&k)!=EOF){
    21         memset(ti, 0, sizeof(ti));
    22         for (int i=0; i<4; i++){
    23             scanf("%s",g[i]);
    24             for (int j=0; j<4; j++){
    25                 if (g[i][j] !='.'){
    26                     ti[g[i][j]-'0']++;
    27                 }
    28             }
    29         }
    30         int flag = 1;
    31         for (int i=0; i<10; i++){
    32             if (2*k < ti[i])
    33                 flag = 0;
    34         }
    35         if (flag)printf("YES
    ");
    36         else printf("NO
    ");
    37     }    
    38     return 0;
    39 }
    View Code

    B. Making Sequences is Fun

    题意:每次给出三个整数 w (1 ≤ w ≤ 1016), m (1 ≤ m ≤ 1016), k (1 ≤ k ≤ 109). 要从整数m开始向后尽可能多的扩充连续的序列,每次扩充的代价为

            s(n) = len(n)*k, len(n) 表示整数 n 的长度。

    分析:二分枚举扩充序列的最后一个整数,计算出这段区间内1的个数num,如果num <= w/k 则满足题意。

    /***************************************
    * File Name:219b.cpp
    * Author:`Wind
    * mail:809098085@qq.com
    * Created Time:2013年12月13日 22:44:57
    *************************************/
    #include <map>
    #include <cmath>
    #include <queue>
    #include <string>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    long long w, m, k;
    long long bit[20];
    void init(){
        bit[1] = 1;
        for (int i=2; i<=17; i++){
            bit[i] = bit[i-1] * 10;
        }
    }
    long long len(long long x){
        long long tt = 0;
        while (x){
            tt += 1;
            x /= 10;
        }
        return tt;
    }
    long long cal(long long x){
        long long ll;
        long long tot = 0;
        while (x >= m){
            ll = len(x);
            long long tmp = max(bit[ll], m);
            tot += (x-tmp+1) * ll;
            x = tmp-1;
        }   
        return tot;
    }
    
    void solve(){
        long long res = m-1;
        long long l = m, r = 100000000, mid;
        r *= r;
        r *= 16;
        while (l <= r){
            mid = (l + r) / 2;
            if (cal(mid) <= w/k){
                l = mid+1;
                res = mid;
            }
            else r = mid-1;
        }
        printf("%I64d
    ",res-m+1);
    }
    int main(){
        init();
        while (scanf("%I64d %I64d %I64d",&w,&m,&k)!=EOF){
            solve();
        }
        return 0;
    }
    View Code

    C. Counting Kangaroos is Fun

    题意:每次给出一个整数 n (1 ≤ n ≤ 5·105),表示袋鼠的数量,接下来一行n个整数si(1 ≤ si ≤ 105)表示每个袋鼠袋子的大小,要求是如果一个袋鼠的袋子

            的2倍不超过另一个袋鼠袋子的大小,那么就可以将这个袋鼠放在大袋子的那个袋鼠袋子里,每个袋鼠只能装一只袋鼠,只能装袋子是空的袋鼠,问最少

           能让多少只袋鼠露在外面。

    分析: 排序,双指针,从中间开始枚举,前一半的袋鼠只用作是被装的,后一半的只用做装别的袋鼠的。

    /***************************************
    * File Name:219c.cpp
    * Author:`Wind
    * mail:809098085@qq.com
    * Created Time:2013年12月14日  7:12:36
    ***************************************/
    #include <map>
    #include <cmath>
    #include <queue>
    #include <string>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 500005;
    int a[maxn];
    int main(){
        int n;
        while (scanf("%d",&n)!=EOF){
            for (int i=0; i<n; i++){
                scanf("%d",&a[i]);
            }
            sort(a, a+n);
            int res = 0;
            int cnt = n-1;
            for (int i=n/2-1; i>=0; i--){
                if (a[i] * 2 <= a[cnt]){
                    cnt--;
                }
            }
            printf("%d
    ",cnt+1);
        }    
        return 0;
    }
    View Code

    D. Counting Rectangles is Fun

    题意:每次给出三个整数 nm and q (1 ≤ n, m ≤ 40, 1 ≤ q ≤ 3·105),表示方格阵的大小,grid中只含有0或1,规定0是白色,1是黑色,白色的矩形是指

            某个子矩阵中每个元素都是0,q个询问,(x1,y1) (x2,y2) 分别表示矩阵的左下角和右上角,问该子矩阵中有多少个白色矩形。

    分析:还没理解,找个代码先慢慢研究。

    #include <cstdio>
    char a[50][50];
    int s[50][50],f[50][50][50],g[50][50][50],ans[50][50][50][50];
    inline bool check(int x0,int y0,int x1,int y1)
    {
        int sum=s[x1][y1]-s[x0-1][y1]-s[x1][y0-1]+s[x0-1][y0-1];
        return(sum==(x1-x0+1)*(y1-y0+1));
    }
    int main()
    {
        int n,m,Q;
        scanf("%d%d%d",&n,&m,&Q);
        for (int i=1;i<=n;i++)
            scanf("%s",a[i]+1);
        for (int i=1;i<=n;i++)
            for (int j=1;j<=m;j++)
                s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+(a[i][j]=='0');
        for (int x=n;x;x--)
            for (int y=m;y;y--)
            {
                for (int i=x;i<=n;i++)
                    for (int j=y;j<=m;j++)
                    {
                        f[y][i][j]+=check(x,y,i,j);
                        g[y][i][j]=g[y+1][i][j]+f[y][i][j];
                    }
                int tmp[50]={0};
                for (int i=x;i<=n;i++)
                    for (int j=y;j<=m;j++)
                    {
                        tmp[j]+=g[y][i][j];
                        ans[x][y][i][j]=ans[x][y][i][j-1]+tmp[j];
                    }
            }
        while (Q--)
        {
            int a,b,c,d;
            scanf("%d%d%d%d",&a,&b,&c,&d);
            printf("%d
    ",ans[a][b][c][d]);
        }
        return(0);
    }
    View Code

    E. Watching Fireworks is Fun

    题意:一条街上将要放烟火,一共有n的烟火燃放点排在一条直线上,相邻距离为1,一共会放m次烟火,知道了每次烟火燃放的时间 ti 和燃放的位置 ai,每次

           给出三个整数 nmd (1 ≤ n ≤ 150000; 1 ≤ m ≤ 300; 1 ≤ d ≤ n). d 表示每一个单位时间可以移动的距离,每个烟火获得的欢乐值为 bi - |ai - x| ,

           起始位置可以任意选择,问最后可以获得的最大欢乐值是多少?

    分析:dp[i][j] 表示第 i 个时间点在 j 位置时获得的总最大欢乐值,可以用滚动数组优化空间

            dp[i][j] = max(dp[i-1][k]) + val[i][j] ,    ( j-t*d<= k <= j+t*d )     

            va[i][j] 表示 在时间点 i 处于 j 位置可以获得的最大欢乐值。

            要用单调队列进行优化。 

  • 相关阅读:
    ZJNU 1216
    ZJNU 1370
    ZJNU 2018
    python装饰器(简单装饰器、叠加装饰器、防止被装饰函数更名、参数化装饰器)
    etcd学习(6)-etcd实现raft源码解读
    etcd学习(5)-etcd的Raft一致性算法原理
    etcd学习(4)-centos7中部署etcd
    etcd学习(3)-grpc使用etcd做服务发现
    etcd学习(2)-etcd中watch源码解读
    etcd学习(1)-etcd的使用场景
  • 原文地址:https://www.cnblogs.com/sky0917/p/3474030.html
Copyright © 2020-2023  润新知