zoukankan      html  css  js  c++  java
  • 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 位置可以获得的最大欢乐值。

            要用单调队列进行优化。 

  • 相关阅读:
    js截取字符串区分汉字字母代码
    List 去处自定义重复对象方法
    63. Unique Paths II
    62. Unique Paths
    388. Longest Absolute File Path
    41. First Missing Positive
    140. Word Break II
    139. Word Break
    239. Sliding Window Maximum
    5. Longest Palindromic Substring
  • 原文地址:https://www.cnblogs.com/sky0917/p/3474030.html
Copyright © 2011-2022 走看看