• Codeforces Round #668 (Div. 2)


    Codeforces Round #668 (Div. 2)

    总览

    A. Permutation Forgery

    原数组reverse一下输出。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int MAXN = 100 + 10;
     
    int t, n;
    int a[MAXN];
     
    int main() {
        scanf("%d", &t);
        while(t--) {
            scanf("%d", &n);
            for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
            reverse(a+1, a+1+n);
            for (int i = 1; i <= n; i++)
                printf("%d%c", a[i], i == n ?  '
    ' : ' ');
        }
     
    }
    

    B. Array Cancellation

    负数前面如果没有足够的正数,就要花硬币消除。否则用前面正数的和抵消一下。

    写嗨了数组大小没开够RE了一发。(SB

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int MAXN = 1e5 + 10;
     
    int t, n;
    LL a[MAXN];
     
    int main() {
        scanf("%d", &t);
        while(t--) {
            scanf("%d", &n);
            LL tmp = 0, ans = 0;
            for (int i = 1; i <= n; i++) {
                scanf("%lld", &a[i]);
                if (a[i] >= 0) tmp += a[i];
                    else {
                        tmp += a[i];
                        if (tmp < 0) ans -= tmp, tmp = 0;
                    }
            }
            printf("%lld
    ", ans);
        }
     
    }
    

    C. Balanced Bitstring

    (s_i)必定要和(s_{i+k})相同。所以直接每隔(k)位看是否同时存在(1)(0),不存在就把 ? 变成相同的就行了。最后再判一下前k位是否满足题意。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int MAXN = 3e5 + 10;
     
     
    int t, n, k;
    char s[MAXN];
     
    bool check() {
        int v1, v0;
        for (int i = 1; i <= k; i++) {
            v0 = v1 = 0;
            for (int j = i; j <= n; j += k) {
                if (s[j] == '0') v0 = 1;
                if (s[j] == '1') v1 = 1;
            }
            if (v1 && v0) return false;
            for (int j = i; j <= n; j += k) {
                if (s[j] == '?') {
                    if (v1) s[j] = '1';
                    else if (v0) s[j] = '0';
                }
            }
        }
     
        v0 = v1 = 0;
        for (int i = 1; i <= k; i++) {
            if (s[i] == '0') v0++;
            else if (s[i] == '1') v1++;
        }
        if (v1 > k/2 || v0 > k/2) return false;
     
        return true;
    }
     
     
    int main() {
        scanf("%d", &t);
        while(t--) {
            scanf("%d%d", &n, &k);
            scanf("%s", s+1);
            printf("%s
    ", check() ? "YES" : "NO");
        }
     
    }
    

    D. Tree Tag

    设树的直径为(d)

    考虑以下三种情况。

    • 如果开局(dist(a,b) <= da),意味着Bob开局即败。
    • 如果(2*da>=d)意味着Alice可以坐镇树的中心,此时Bob必败。
    • 如果(2*da>=db)意味着Alice可以追上Bob,此时Bob必败。

    如果上面三种情况都不满足,那么Bob必胜。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int MAXN = 1e5 + 10;
    const LL inf = 0x3f3f3f3f3f3f3f3f;
     
     
    int t;
    int n, a, b, da, db;
    vector<int> V[MAXN];
    int d[MAXN], v[MAXN], dep[MAXN];
    int ans = 0;
     
    void dp(int x) {
        v[x] = 1;
        for (auto y : V[x]) {
            if (v[y]) continue;
            dp(y);
            ans = max(ans, d[x]+d[y]+1);
            d[x] = max(d[x], d[y]+1);
        }
    }
     
    void dfs(int x, int fa) {
        for (auto y : V[x]) {
            if (y == fa) continue;
            dep[y] = dep[x] + 1;
            dfs(y, x);
        }
    }
     
    int main() {
        scanf("%d", &t);
        while(t--) {
            scanf("%d%d%d%d%d", &n, &a, &b, &da, &db);
            for (int i = 1; i <= n; i++) {
                d[i] = 0;
                v[i] = 0;
                dep[i] = 0;
                V[i].clear();
            }
            for (int i = 1; i < n; i++) {
                int x, y;
                scanf("%d%d", &x, &y);
                V[x].push_back(y);
                V[y].push_back(x);
            }
     
            ans = 0;
            dp(1);
            dfs(a, 0);
     
            if (da * 2 >= min(ans, db) || dep[b] <= da) printf("Alice
    ");
                else printf("Bob
    ");
        }
    }
    

    E. Fixed Point Removal

    遍历时,用(sum[i])记录可以被消除的数字个数的前缀和。那么只要(0<=i-a[i]<=sum[i-1])(a[i])就可以被消除。

    再用(d[i])记录着每一个被消除的数字的(i-a[i]),不能被消除记为(inf)

    我们考虑,前面的数字消除会如何影响后面数字呢?一定是让某些原先不可消除的数字变的可消除了。

    对于每次询问((x,y)),如何消除前(x)个数字的影响呢?用(sum[i-1])减去(sum[x])就好了。答案即为区间([x+1, n-y])(d[i] <= sum[i-1]-sum[x])的数字个数。区间内小于(k)的数字个数可以用树状数组或者主席树做。

    本题纯属口胡,最后没调出来。可能是错的(QAQ

  • 相关阅读:
    是否需要有代码规范
    结对同伴作业复审
    个人作业-四则运算生成
    个人博客-week7
    个人博客作业Week3
    结对编程项目总结
    个人项目总结
    个人博客作业Week2
    第二次结对作业
    个人作业3——个人总结(Alpha阶段)
  • 原文地址:https://www.cnblogs.com/ruthank/p/13624566.html
Copyright © 2020-2023  润新知