• Educational Codeforces Round 94 (Rated for Div. 2)


    总览


    不太常打CF。后来想了想,虽然退休了,还是决定给名字换点颜色。

    A. String Similarity

    答案字符串可以由(s[1..n])的第(1)位, (s[2..n+1])的第(2)位, (s[3..n+2])的第(3)位...构成。即原字符串的奇数位。

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 60;
    typedef long long LL;
    const int inf = 0x3f3f3f3f;
     
    char s[MAXN * 2];
     
    int n, t;
    int main() {
        scanf("%d", &t);
        while(t--) {
            scanf("%d", &n);
            scanf("%s", s);
            for (int i = 0; i < 2*n; i++) {
                if (i%2 == 0) printf("%c", s[i]);
            }
            printf("
    ");
        }
     
    }
    

    B. RPG Protagonist

    枚举第一个人取剑的数量,那么第一个人取战斧的数量是可以计算的。第二个人只要贪心从剑和战斧先取重量较小的,再用较大的填满背包即可。

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 60;
    typedef long long LL;
    const int inf = 0x3f3f3f3f;
    
    int n, t;
    int main() {
       scanf("%d", &t);
       while(t--) {
           LL p, f, cnts, cntw, s, w;
           scanf("%lld%lld%lld%lld%lld%lld", &p, &f, &cnts, &cntw, &s, &w);
           LL ans = 0;
           for (LL i = 0; i <= cnts; i++) {
               if (i*s > p) break;
               LL j = min( (p-i*s)/w, cntw );
    
               LL x, y;
               if (s > w) {
                   x = min( f/w, cntw-j );
                   y = min( (f - x*w) / s, cnts-i );
               } else {
                   y = min( f/s, cnts-i );
                   x = min( (f - y*s) / w, cntw-j );
               }
               ans = max(ans, y + x + i + j);
           }
           printf("%lld
    ", ans);
       }
    
    }
    

    C. Binary String Reconstruction

    (0)的两边一定都是(0)。所以可以先遍历处理(0)的位置,标记两边为(0),被标记的地方都看作(1),然后通过剩下的(1)判断是否合法。当1的两边都已经被标记为(0)的时候为不合法。

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 1e5 + 100;
    typedef long long LL;
    const int inf = 0x3f3f3f3f;
     
    char s[MAXN];
    int v[MAXN];
    int n, t, x;
     
    bool solve() {
        int len = strlen(s+1);
        
        for (int i = 1; i <= len; i++) v[i] = 1;
     
        for (int i = 1; i <= len; i++) {
            if (s[i] == '0') {
                if (i-x > 0) v[i-x] = 0;
                if (i+x <= len) v[i+x] = 0;
            }
        }
     
        for (int i = 1; i <= len; i++) {
            if (s[i] == '1') {
                int flag = 0;
                if (i-x > 0 && v[i-x] != 0) flag++;
                if (i+x <= len && v[i+x] != 0) flag++;
                if (!flag) return false;
            }
        }
     
        for (int i = 1; i <= len; i++)
            printf("%d", v[i]);
        puts("");
        return true;
     
    }
     
    int main() {
        scanf("%d", &t);
        while(t--) {
            scanf("%s%d", s+1, &x);
            if (!solve()) printf("-1
    ");
        }
     
    }
    

    D. Zigzags

    预处理(sum[i][j]),即前(i)个数中存在的数字(j)的个数。

    枚举元组((i,j,k,l))(j)(k)的位置,设为(l)(r)

    那么此时满足题意的元组数量即为 (l)前面的(a[r])的个数( * r)后面的(a[l])的个数。更新答案即可。

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 3000 + 100;
    typedef long long LL;
    const int inf = 0x3f3f3f3f;
     
    int a[MAXN];
    int sum[MAXN][MAXN];
    int n, t, x;
     
     
    int main() {
        scanf("%d", &t);
        while(t--) {
            scanf("%d", &n);
            for (int i = 1; i <= n; i++) {
                scanf("%d", &a[i]);
                for (int j = 1; j <= n; j++) sum[i][j] = sum[i-1][j];
                sum[i][a[i]]++;
            }
     
            LL ans = 0;
            for (int i = 1; i <= n; i++)
            for (int j = i+1; j <= n; j++)
                ans += 1ll * sum[i-1][a[j]] * (sum[n][a[i]] - sum[j][a[i]]);
     
            printf("%lld
    ", ans);
        }
    }
    

    E. Clear the Multiset

    最优解可能是全都竖着消,或者横着消min次+剩余连通块的处理次数之和。min为数组最小值。

    剩余连通块可以递归求解。

    写挫了一发。第二发过了。

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 5000 + 100;
    typedef long long LL;
    const int inf = 0x3f3f3f3f;
    
    int a[MAXN];
    int n, t, x;
    
    int solve(int l, int r, int h) {
        if (l == r) return a[l]-h != 0; //这里直接写return 1结果被hack了。hack数据1 0
    
        int ans = 0, minX = inf, cnt = 0;
        for (int i = l; i <= r; i++) minX = min(minX, a[i]-h);
        for (int i = l; i <= r; i++) ans += a[i]-h != 0;
    
        int s = -1, tmp = 0;
        for (int i = l; i <= r; i++) {
            if (s == -1 && a[i]-h > minX) s = i;
            if (s != -1 && (i == r || a[i+1]-h == minX)) {
                tmp += solve(s, i, minX+h);
                s = -1;
            }
        }
        ans = min(ans, minX + tmp);
        return ans;
    }
    
    int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++)
            scanf("%d", &a[i]);
        printf("%d", solve(1, n, 0));
    }
    
    

    F. x-prime Substrings

    too vegetable to solve

    G. Mercenaries

    too vegetable to solve

  • 相关阅读:
    2017ccpc全国邀请赛(湖南湘潭) E. Partial Sum
    Codeforces Round #412 C. Success Rate (rated, Div. 2, base on VK Cup 2017 Round 3)
    2017 中国大学生程序设计竞赛 女生专场 Building Shops (hdu6024)
    51nod 1084 矩阵取数问题 V2
    Power收集
    红色的幻想乡
    Koishi Loves Segments
    Wood Processing
    整数对
    Room and Moor
  • 原文地址:https://www.cnblogs.com/ruthank/p/13562874.html
Copyright © 2020-2023  润新知