• Codeforces Round #696 (Div. 2)


    Codeforces Round #696 (Div. 2)

    A - Puzzle From the Future

    贪心, 让长度最长, 每次试 +1,

    int main() {
        IOS;
        for (cin >> _; _; --_) {
            string s; cin >> n >> s; m = -1;
            for (int i = 0; i < n; ++i) {
                int c = s[i] - '0';
                if (c + 1 != m) s[i] = '1', m = c + 1;
                else s[i] = '0', m = c;
            }
            cout << s << '
    ';
        }
        return 0;
    }
    

    B - Different Divisors

    1, a, b, a * b

    a, b为质数, 且 a - 1 >= d, b - a >= d即可

    int prime[N], tot;
    bool v[N];
     
    void init() {
        for (int i = 2; i <= 2e6; ++i) {
            if (!v[i]) prime[++tot] = i;
            for (int j = 1; j <= tot && prime[j] <= 2e6 / i; ++j) {
                v[i * prime[j]] = 1;
                if (i % prime[j] == 0) break;
            }
        }
    }
     
    int main() {
        IOS; init();
        for (cin >> _; _; --_) {
            cin >> n; ll ans = *lower_bound(prime + 1, prime + tot + 1, 1 + n);
            cout << (ans * (*lower_bound(prime + 1, prime + tot + 1, ans + n))) << '
    ';
        }
        return 0;
    }
    

    C - Array Destruction

    枚举哪个数和最大数一起消去就好, 在模拟判断是否满足, 听说有人是 (O(n^3)), 那就没啥算法了, 就是枚举模拟题意

    int s[N];
     
    bool work(multiset<int> q1, int id, vector<PII>& x) {
        int a = *q1.begin(); q1.erase(q1.begin()); q1.erase(q1.find(-s[id]));
        x.pb({ -a, s[id] }); bool f = 1;
        for (int i = 1; i < n && f; ++i) {
            int mx = *q1.begin(); q1.erase(q1.begin());
            auto it = q1.find(a - mx);
            if (it == q1.end()) f = 0;
            else x.pb({ -mx, -*it }), q1.erase(it), a = mx;
        }
        if (f) return 1; vector<PII>().swap(x);
        return 0;
    }
     
    int main() {
        IOS;
        for (cin >> _; _; --_) {
            multiset<int> q1; vector<PII> y; bool f = 0;
            cin >> n; rep(i, 1, n * 2) cin >> s[i], q1.insert(-s[i]); sort(s + 1, s + 1 + n * 2);
            for (int i = 1; i < n * 2 && !f; ++i) f = work(q1, i, y);
            if (f) {
                cout << "YES
    " << y[0].fi + y[0].se << '
    ';
                for (auto& i : y) cout << i.fi << ' ' << i.se << '
    ';
            }
            else cout << "NO
    ";
        }
        return 0;
    }
    

    D - Cleaning

    差分, 最左边的石子只能靠第2堆消去, 以此类推

    a[1] - a[1], (a[2] - a[1]) - (a[2] - a[1]), (a[3] - a[2] + a[1]) - (a[3] - a[2] + a[1]), ... , (a[n] - a[n - 1] + a[n - 2] - ... + ((-1)^{n - 1 & 1}) * a[1]) - (a[n] - a[n - 1] + a[n - 2] - ... + ((-1)^{n - 1 & 1}) * a[1])

    最终目标是所有 b[i] = a[i] - a[i- 1] + a[i - 2] - ... + ((-1)^{i - 1 xor 1}) * a[1] >= 0 且 b[n] = 0

    考虑交换 i 和 i + 1, 那么 b[1~i-1] >= 0, 且 b[i] += a[i + 1] - a[i] >= 0, 且 i + 1 ~ n, b[i + 2k + 1] -= 2 * (a[i + 1] - a[i]), b[i + 2k] += 2 * (a[i + 1] - a[i])

    所以我们还要预处理 b[i], b[i + 2], ..., b[n - i & 1 ? n : n - 1] 之间的最小值

    这样就是 线性 枚举交换 i 和 i + 1, 判断是否可行即可

    int main() {
        IOS;
        for (cin >> _; _; --_) {
            cin >> n; vector<ll> a(n + 1), b(n + 1), c(n + 1);
            rep (i, 1, n) cin >> a[i], b[i] = a[i];
            bool f = 1;
            rep (i, 1, n) c[i] = b[i] -= b[i - 1], f = f & (b[i] >= 0);
            f = f & b[n] == 0;
            per (i, n - 2, 1) umin(c[i], c[i + 2]);
            rep (i, 1, n - 1) {
                if (b[i - 1] < 0 || f) break;
                int t = a[i + 1] - a[i];
                if (b[i] + t < 0 || c[i + 1] - 2 * t < 0 || (i + 2 <= n && c[i + 2] + 2 * t < 0)) continue;
                if (b[n] + 2 * (n - i & 1 ? -t : t) == 0) f = 1; 
            }
            cout << (f ? "YES
    " : "NO
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    常用Linux命令总结
    mysql基础归纳
    第一次使用Ubuntu20.04系统-遇坑小记
    Linux操作系统常用命令
    单例模式
    MVC设计模式
    SpringMVC体系结构简要描述
    报错:数据库连接问题
    数据库增删改查语句
    JDBC关键步骤(简化版)
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/14323040.html
Copyright © 2020-2023  润新知