A. Absolute Maximization

给出一个数组,每次可以选择两个数,交换两个数二进制表示的同一位,问经过若干次操作后,得到的数组中最大值减最小值的差最大是多少。
思路:统计所有数二进制每一位的情况,贪心分配最大值和最小值即可。
AC Code:
#include <bits/stdc++.h>
typedef long long ll;
const int N = 1e5 + 5;
int t, n;
int a[N], cnt[N];
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
std::cin >> t;
while(t --) {
std::cin >> n;
memset(cnt, 0, sizeof(cnt));
for(int i = 1; i <= n; i ++) {
std::cin >> a[i];
for(int j = 0; j <= 13; j ++) {
cnt[j] += (a[i] >> j & 1);
}
}
int max = 0, min = 0;
for(int i = 0; i <= 13; i ++) {
if(cnt[i] == n)
min += (1 << i);
if(cnt[i])
max += (1 << i);
}
std::cout << max - min << '\n';
}
return 0;
}
B. Incinerate

给出n个怪物的生命值h数组和攻击力p数组,给出这个人的攻击力k,每次攻击都会对所有的怪物有k的伤害,同时k会减少存活怪物中攻击力最少的那个值,问经过若干次攻击之后能否杀死全部怪物。
思路:模拟即可。
AC Code:
#include <bits/stdc++.h>
typedef long long ll;
#define int long long
const int N = 1e5 + 5;
int t, n, k;
struct node {
int h, p;
} e[N];
bool cmp(node a, node b) {
return a.p < b.p;
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
std::cin >> t;
while(t --) {
std::cin >> n >> k;
for(int i = 1; i <= n + 2; i ++) {
e[i] = {0, 0};
}
for(int i = 1; i <= n; i ++) {
std::cin >> e[i].h;
}
for(int i = 1; i <= n; i ++) {
std::cin >> e[i].p;
}
std::sort(e + 1, e + 1 + n, cmp);
int hh = 0;
bool flag = true, ff = false;
for(int i = 1; i <= n; i ++) {
e[i].h -= hh;
if(e[i].h <= 0) continue;
if(e[i].h > 0 && ff)
k -= e[i].p, ff = false;
while(e[i].h > 0 && k > 0) {
e[i].h -= k;
hh += k;
if(e[i].h > 0)
k -= e[i].p;
else
ff = true;
}
if(k <= 0 && e[i].h > 0) {
flag = false;
break;
}
}
std::cout << (flag ? "YES" : "NO") << '\n';
}
return 0;
}
os:一开始wa了一发,因为减的时候没考虑下一个不一定存活。
C. Another Array Problem

给出一个数组a,每次可以选择任意连续一段,将这一段中的所有数换成边界两数差的绝对值,问经过若干次操作后,数组和的最大值是多少。
思路:我们可以将相邻的两个数变为0,两次操作即可达到。考虑极端情况,我们是可以将数组中所有数变为数组中最大的数,这样无非是最优的情况。但是对于n==3的情况,若是最大值在边界,那可以将数组中所有的数变为最大值,否则只能枚举所有的可能性;n==2时,枚举结果即可。
AC Code:
#include <bits/stdc++.h>
typedef long long ll;
#define int long long
const int N = 2e5 + 5;
int t, n, k;
int a[N];
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
std::cin >> t;
while(t --) {
std::cin >> n;
int max = 0;
for(int i = 1; i <= n; i ++) {
std::cin >> a[i];
max = std::max(max, a[i]);
}
if(n == 2) {
std::cout << std::max(2 * abs(a[1] - a[2]), a[1] + a[2]) << '\n';
continue;
}
if(n > 3) {
std::cout << n * max << '\n';
continue;
}
std::cout << std::max({a[1] + a[2] + a[3], 3 * abs(a[1] - a[2]), 3 * abs(a[2] - a[3]), 3 * a[1], 3 * a[3]}) << '\n';
}
return 0;
}
os:这个题rating2000?