Codeforces Round #618 (Div. 2)
【A.Non-zero】
【题目大意】
有一个长度为n的整数序列,你每次可以选择一个数加上一,问你总共加多少次可以让序列的和与积均不为0
【解题思路】
统计其中0的个数,并将0全部变为1,然后此时如果总和为0任意选一个数加上一,总操作次数即为答案
【AC代码】
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
int sum = 0, ans = 0;
for (int i = 1; i <= n; ++i) {
int x;
cin >> x;
if (!x) {
++ans, ++sum;
}
else sum += x;
}
if (!sum) ++ans;
cout << ans << endl;
}
return 0;
}
【B.Assigning to Classes】
【题目大意】
有一个长度为2n的序列,让你将其分成两个长度为奇数的序列使得两个序列的中位数之差的绝对值最小
【解题思路】
手动模拟发现其实就是排序过后的a[n + 1] - a[n]
【AC代码】
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
const int maxn = 2e5 + 10;
int a[maxn];
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
int nn = n << 1;
for (int i = 1; i <= nn; ++i) {
cin >> a[i];
}
sort(a + 1, a + nn + 1);
cout << abs(a[n + 1] - a[n]) << endl;
}
return 0;
}
【C.Anu Has a Function】
【题目描述】
定义f(x, y) = (x | y) - y,给定序列a问怎样排列a使得f(f(…f(a[0], a[1]), a[2] … ), a[n])最大
【解题思路】
模拟发现f(x, y)是将x和y二进制下相同1的地方变成了0,那么也就是说f(f(…f(a[0], a[1]), a[2] … ), a[n])是将a[0]和a[1]…a[n]二进制下相同1的位置变成了0,那么我们可以预处理出b[i] = a[0] | a[1] | … | a[i - 1] | a[i + 1] | … | a[n],然后O(n)遍历序列a找到max(f(a[i], b[i])),将a[i]放置序列首位置即可即可,其他数可以任意放置
【AC代码】
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const int maxn = 1e5 + 10;
ll a[maxn], b[maxn], c[maxn];
inline bool cmp(int x, int y) { return x > y; }
inline int fun(int x, int y) { return ((x | y) - y); }
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int n;
cin >> n;
ll sum = 0;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
}
b[2] = a[1];
c[n - 1] = a[n];
for (int i = 2; i <= n; ++i) {
b[i] = b[i - 1] | a[i - 1];
c[n - i] = c[n - i + 1] | a[n - i + 1];
}
for (int i = 1; i <= n; ++i) {
b[i] |= c[i];
}
int Max = 0;
int tag = -1;
for (int i = 1; i <= n; ++i) {
int tmp = fun(a[i], b[i]);
if (tmp > Max) {
Max = tmp;
tag = i;
}
}
if (tag != -1) cout << a[tag] << " ";
for (int i = 1; i <= n; ++i) {
if (tag == i) continue;
cout << a[i] << " ";
}
cout << endl;
}