Codeforces Round 1008 (Div. 2)

A. Final Verdict

题目大意

给你一个数组a,每次把他拆分为等长的k个子序列,然后用子序列的平均数替换掉这个子序列,问最后能不能让数组只剩下一个数字x

解题思路

无论怎么划分,最后的总值是不变的,所以只需要看总和是不是 n*x 即可

代码实现

#include <bits/stdc++.h>

using i64 = long long;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    int tt;
    std::cin >> tt;

    while (tt--) {
        i64 n, x;
        std::cin >> n >> x;

        std::vector<int> a(n);
        for (int i = 0; i < n; i++) {
            std::cin >> a[i];
        }

        if (std::accumulate(a.begin(), a.end(), 0ll) == x * n) {
            std::cout << "YES\n";
        } else {
            std::cout << "NO\n";
        }
    }
}

B. Vicious Labyrinth

题目大意

给你一个长度为n的数组,设最后的总和为他们当前的位置到n的距离和(从1开始,每个位置可以有多个数字),可以改变他们的位置k次,但是不能原地传送,问最后的最小和是多少

解题思路

显然要让所有的数字尽可能都传送到n的位置,如果不行则传送到n-1,因此只需要根据奇偶性来判断是n还是n-1即可

代码实现

#include <bits/stdc++.h>

using i64 = long long;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    int tt;
    std::cin >> tt;

    while (tt--) {
        int n, k;
        std::cin >> n >> k;

        for (int i = 0; i < n - 2; i++) {
            std::cout << n - 1 + k % 2 << " ";
        }
        std::cout << n << " " << n - 1 << "\n";
    }
}

C. Breach of Faith

题目大意

数组a的每个数字各不相同,并且满足a1 = a2 - a3 + a4 - a5...,现在删除a中一个数字并打乱顺序得到数组b,要求复原出任意一个可以由b推出的a

解题思路

式子其实就是奇数位置加偶数位置减,所以让奇数位置的数字都是较大的一半,偶数位置是较小的一半就能得到一个数字,使得他是数组最大值,排序之后安装奇偶放置即可

代码实现

#include <bits/stdc++.h>

using i64 = long long;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    int tt;
    std::cin >> tt;

    while (tt--) {
        int n;
        std::cin >> n;

        std::vector<i64> b(2 * n), a(2 * n + 1);
        for (int i = 0; i < 2 * n; i++) {
            std::cin >> b[i];
        }
        std::sort(b.begin(), b.end());

        for (int i = 0; i < n - 1; i++) {
            a[2 * i + 1] = b[i];
            a[2 * n - 1] -= b[i];
        }
        for (int i = n - 1; i < 2 * n; i++) {
            a[(i - n + 1) * 2] = b[i];
            a[2 * n - 1] += b[i];
        }

        for (auto x : a) {
            std::cout << x << " \n"[x == a.back()];
        }
    }
}

D. Scammy Game Ad

题目大意

游戏关卡有多对左门和右门,每个门执行给定的加法或乘法操作。左右初始人数都为1,要求最大化两条通道的总人数

解题思路

每次计算已经分配的人数和暂时无法确认的人,对于未知分配的人显然乘更优,因此每次都把这部分的都分配给乘的一部分,然后计算这一次可以得到的无法确认分配的人,最后把左右和未知的部分全部加起来即可

代码实现

#include <bits/stdc++.h>

using i64 = long long;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    int tt;
    std::cin >> tt;

    while (tt--) {
        int n;
        std::cin >> n;

        i64 l = 1, r = 1, add = 0;
        for (int i = 0; i < n; i++) {
            char op1, op2;
            int a1, a2;
            std::cin >> op1 >> a1 >> op2 >> a2;

            if (op1 == '+' && op2 == '+') {
                add += a1 + a2;
            } else if (op1 == '+' && op2 == 'x') {
                r += add;
                add = a1 + r * (a2 - 1);
            } else if (op1 == 'x' && op2 == '+') {
                l += add;
                add = a2 + l * (a1 - 1);
            } else {
                if (a1 == a2) {
                    add += (l + r + add) * (a1 - 1);
                } else if (a1 < a2) {
                    r += add;
                    add = l * (a1 - 1) + r * (a2 - 1);
                } else {
                    l += add;
                    add = l * (a1 - 1) + r * (a2 - 1);
                }
            }
        }

        std::cout << l + r + add << "\n";
    }
}

E. Finding OR Sum

题目大意

交互题,未知xy,你可以询问两次n,每次得到 \((n|x)+(n|y)\) 的值,之后给你一个m,要求回答 \((m|x)+(m|y)\) 的值

解题思路

询问形如1010...和0101...的数即可获得xy在奇偶位上的信息,接下来只需要对二进制数的奇偶位判断处理即可

代码实现

#include <bits/stdc++.h>

using i64 = long long;

const int q1 = 715827882, q2 = 357913941;

int main() {
    int tt;
    std::cin >> tt;

    while (tt--) {
        int a1, a2, x = 0, y = 0, m;
        std::cout << q1 << std::endl;
        std::cin >> a1;
        std::cout << q2 << std::endl;
        std::cin >> a2;

        a1 -= q1 * 2;
        a2 -= q2 * 2;

        for (int i = 0; i < 30; i++) {
            if (i & 1) {
                if (a2 & (1 << i)) {
                    x |= (1 << i);
                }
                if (a2 & (1 << (i + 1))) {
                    x |= (1 << i);
                    y |= (1 << i);
                }
            } else {
                if (a1 & (1 << i)) {
                    x |= (1 << i);
                }
                if (a1 & (1 << (i + 1))) {
                    x |= (1 << i);
                    y |= (1 << i);
                }
            }
        }

        std::cout << "!" << std::endl;
        std::cin >> m;
        std::cout << (m | x) + (m | y) << std::endl;
    }
}
posted @ 2025-03-19 22:52  udiandianis  阅读(167)  评论(0)    收藏  举报