• Codeforces Round #717 (Div. 2) 个人题解 A~C (A思維,B位運算,C背包DP)


    1516A. Tit for Tat

    題意:

    給定大小為 (n) 的數組和可操作次數 (k)

    • 每次操作都選定兩個數(如果 (1 le a_i) ),使第一個數 - (1) ,另一個數 + (1)

    輸出字典序最小的數組

    思路:

    既然要輸出字典序最小,那麽肯定是選最前面 - 1,最後 + 1

    void solve() {
        int n, k;
        cin >> n >> k;
        int a[n + 1];
        for (int i = 1; i <= n; ++i) cin >> a[i];
        int i = 1, j = n;
        while (true) {
            if (i == j || k == 0) break;
            if (a[i] >= 1) a[i] -= 1, a[j] += 1, k--;
            else
                i++;
        }
        for (int i = 1; i <= n; ++i) cout << a[i] << " ";
        cout << "
    ";
    }
    

    1516B. AGAGA XOOORRR

    題意:

    思路:

    我采取的方法是模擬,首先求出全部元素的 XOR 結果,如果 (s = 0) 則是元素兩兩相等的情況比如:(0,2,2,1,1,3,3...) 此時輸出 YES 即可。

    維護 (t) 如果 (t == s) 則説明前面已使用的一段可以 XOR 為同一個值,此時 (t = 0,cnt += 1)

    如果最後 cnt > 2 && t == 0 則説明數組完全可以通過 XOR 操作簡化為相同的值

    void solve() {
        int n;
        cin >> n;
        vector<int> a(n);
        for (int &x : a) cin >> x;
        int s = 0;
        for (int x : a) s ^= x;
        if (s == 0) {
            cout << "YES
    ";
            return;
        }
        int t = 0, cnt = 0;
        for (int i = 0; i < n; ++i) {
            t ^= a[i];
            if (t == s) cnt++, t = 0;
        }
        if (cnt > 2 && t == 0) cout << "YES
    ";
        else
            cout << "NO
    ";
    }
    

    下面代碼為官方 AC 代碼:

    void solve() {
        int n;
        cin >> n;
        vector<int> a(n + 1);
        for (int i = 1, x; i <= n; ++i) {
            cin >> x;
            a[i] = a[i - 1] ^ x;
        }
        bool f = !a[n];
        for (int i = 1; i <= n; ++i)
            for (int j = i + 1; j <= n; ++j)
                f |= (a[i] == (a[j] ^ a[i]) && a[i] == (a[n] ^ a[j]));
        cout << (f ? "YES
    " : "NO
    ");
    }
    

    1516C. Baby Ehab Partitions Again

    題意:

    將數組劃分為兩個子序列,如果存在兩個子序列之和相等則被稱爲 “好數組” 現在請問是否能刪除幾個元素使得數組不是 “好數組”

    思路:

    首先,让我们检查一下数组是否已经很好。 这可以通过背包dp完成。 如果是,则答案为0。否则,可以始终删除一个元素以使其良好,这是找到它的方法:由于可以对数组进行分区,因此其总和为偶数。 因此,如果我们删除一个奇数元素,它将是奇数,并且将无法对其进行分区。 如果没有奇数元素,那么所有元素都是偶数。 但是,您可以将所有元素除以2,而无需更改答案。 为什么? 因为将所有内容都除以2后在新数组中进行的分区就是在原始数组中进行的分区,反之亦然。 我们只是重新缩放了一切。 因此,当所有元素都是偶数时,您可以继续除以2,直到其中一个元素变为奇数。 删除它,您就完成了。 如果您想用一句话来解决,请删除可能的最小有效位最小的元素。
    另外,出于类似的推理,您可以先将整个数组除以其gcd,然后删除任何奇数元素(因为gcd为1,该元素必须存在)

    int dp[200010];
    void solve() {
        int n;
        cin >> n;
        vector<int> a(n + 1);
        int d = 0;
        for (int i = 1; i <= n; ++i) cin >> a[i], d = __gcd(d, a[i]);
        for (int i = 1; i <= n; ++i) a[i] /= d;
        dp[0] = 1;
        int S = 0, id = 0;
        for (int i = 1; i <= n; ++i) {
            S += a[i];
            if (a[i] & 1) id = i;
            for (int j = S; j >= a[i]; j--) dp[j] |= dp[j - a[i]];
        }
        if (S & 1 || dp[S / 2] == 0) cout << "0";
        else
            cout << "1
    "
                 << id;
    }
    

    The desire of his soul is the prophecy of his fate
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    Bzoj1597 [Usaco2008 Mar]土地购买
    Bzoj1500 [NOI2005]维修数列
    模拟7 题解
    模拟6 题解
    模拟5 题解
    远古杂题 2
    远古杂题 1
    [NOIP2013]华容道 题解
    奇袭 CodeForces 526F Pudding Monsters 题解
    图论杂题
  • 原文地址:https://www.cnblogs.com/RioTian/p/14691130.html
Copyright © 2020-2023  润新知