Codeforces Round #726 (Div. 2)
Codeforces Round #726 (Div. 2)
傻逼场
A
一堆数字考虑添加非负整数使得平均数为1.
int t, n;
int main() {
cin >> t;
for ( ; t--; ) {
cin >> n;
int sum = 0;
for (int i = 1, x; i <= n; ++i) {
cin >> x;
sum += x;
}
if (sum > n) {
cout << sum - n << '\n';
}
else if (sum == n) {
cout << 0 << '\n';
}
else {
cout << 1 << '\n';
}
}
return 0;
}
B
给你一个起点,然后要求你给出两个点,使得从起点经过这两个点再回去的距离最远。
很显然选择几个角即可。
int t;
long long n, m, i, j;
int main() {
cin >> t;
while (t--) {
cin >> n >> m >> i >> j;
cout << 1 << " " << 1 << " " << n << " " << m << '\n';
}
return 0;
}
C
给你一个序列 \(h\) 要求你重新排列 \(h\) 使得 \(|h_1-h_n|\) 最小并且 \(h_i\le h_{i+1}\) 的对数最多。
我们考虑首先对于 \(h\) 排序,然后找出来最小的差值,设为 \(h_{pos}\) 和 \(h_{pos+1}\)
我们考虑 \(h_{pos},h_{pos+2},\cdots,h_n,h_1,\cdots h_{pos-1},h_{pos+1}\) 即可,这样子的对数为 \(n-2\)(特殊情况,在 \(n=2\) 的时候为 \(1\))
int a[N];
int main() {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
}
std::sort(a + 1, a + 1 + n);
int mn = INF;
for (int i = 2; i <= n; ++i) {
mn = min(a[i] - a[i - 1], mn);
}
for (int i = 2; i <= n; ++i) {
if (mn == a[i] - a[i - 1]) {
cout << a[i - 1] << ' ';
for (int j = i + 1; j <= n; ++j) {
cout << a[j] << ' ';
}
for (int j = 1; j < i - 1; ++j) {
cout << a[j] << ' ';
}
cout << a[i];
cout << '\n';
break;
}
}
}
return 0;
}
D
我们考虑 \(x\) 是奇数,非 \(2\) 的幂次的偶数,和 \(2\) 的 \(x\) 次幂的情况。
如果x是一个奇数,那么考虑减去的是一个\(D\)(一定为奇数),考虑剩下的数字 \(n-D\) 是一个非 \(2\) 的幂次的偶数(这是显然的,因为他被 \(D\) 整除)。
考虑非 \(2\) 的幂次的偶数,我们可以随便去掉一个因数,让它变成一个奇数。这样子只要我们每次把它变成奇数,最后直至 \(x\) 是个素数的时候对手会输。
考虑2的幂次,答案显然和 \(\log(x)\) 有关系,因为如果不把 \(x\) 变成 \(x/2\),那么就会变成上述的第二种情况,这种情况对于我们是必输的。
int main() {
cin >> t;
while (t--) {
cin >> n;
if (n & 1) {
cout << "Bob\n";
}
else {
if ((n & -n) != n) {
cout << "Alice\n";
}
else {
int len = log2(n);
if (len & 1) {
cout << "Bob\n";
}
else {
cout << "Alice\n";
}
}
}
}
return 0;
}
E
写了个comment
it is easy to understand the ans is the prefix string of s
, so we suppose current ans is \(a(1\le a\le i)\), now we need compare \(i+1\) and \(a\).
if \(s[i+1]<s[i\%a+1]\)(pos begin at 1), then \(i+1\) is bterr than \(a\).
else if \(s[i+1]>s[i\%a+1]\),\(i+1\) is worse.
else if \(s[i+1]=s[i\%a+1]\),\(i+1\) is worse,becase \(s[1:a - (i \% a + 1)]\ge s[i\%a+2,a]\),if not \(a-(i\%a + 1)\) is better than \(a\)。
懒得再写一遍了。
int main() {
int n, k;
cin >> n >> k;
int ans = 1;
cin >> s + 1;
for (int i = 1; i <= n; ++i) {
if (s[(i - 1) % ans + 1] < s[i]) {
break;
}
else if (s[(i - 1) % ans + 1] > s[i]) {
ans = i;
}
}
for (int i = 1; i <= k; ++i) {
cout << s[(i - 1) % ans + 1];
}
return 0;
}
F
原题 NOIol 序列。
说一下,我们考虑原图是不是二粉兔即可。
如果是个二粉兔,那么考虑左右的差值即可。否则考虑对于答案的奇偶性即可。
#include <bits/stdc++.h>
using namespace std;
#define N 200005
struct ji {
int nex, to;
} edge[N << 1];
int E, t, n, m, p, head[N], bl[N], a[N], b[N], sum[N];
long long x, y;
void add(int x, int y)
{
edge[E].nex = head[x];
edge[E].to = y;
head[x] = E++;
}
bool dfs2(int k, int p)
{
if (bl[k] >= 0)
return bl[k] == p;
if (p)
x += sum[k];
else
y += sum[k];
bl[k] = p;
bool flag = 1;
for (int i = head[k]; i != -1; i = edge[i].nex)
flag &= dfs2(edge[i].to, p ^ 1);
return flag;
}
int main()
{
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
E = 0;
memset(bl, 0, sizeof(bl));
memset(sum, 0, sizeof(sum));
memset(head, -1, sizeof(head));
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 1; i <= n; i++)
scanf("%d", &b[i]);
for (int i = 1; i <= n; ++i) {
sum[i] = a[i] - b[i];
}
for (int i = 1; i <= m; i++) {
scanf("%d%d", &x, &y);
add(x, y);
add(y, x);
}
memset(bl, -1, sizeof(bl));
bool flag = 1;
for (int i = 1; i <= n; i++)
if (bl[i] < 0) {
x = y = 0;
p = dfs2(i, 0);
if (p)
flag &= (x == y);
else
flag &= ((x + y) % 2 == 0);
}
if (flag)
printf("YES\n");
else
printf("NO\n");
}
}