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;}
}