AtCoder Grand Contest 020
tourist's contest...ssfd
A - Move and Win
想不到好的博弈方法,我就直接暴力了...
可以确定的是,如果一个人觉得他走这个方向是最优的,那么他肯定会一直走下去。
那么就枚举四种情况,第一个人往左(往右),第二个人往左(往右)。
当第一个人往左(或往右)时,另一个人怎么走都输时他就能赢,否则他就输了。
看了别人的代码,好像判一下 $b - a$ 的奇偶性就行了..........
好像是的,因为每个人走完一步之后,之间的差的奇偶性还是不改变。
我傻逼了。
#include <bits/stdc++.h> using namespace std; int main() { int n, a, b; scanf("%d%d%d", &n, &a, &b); bool ans1 = 0, ans2 = 0, ans3 = 0, ans4 = 0; for (int i = a, j = b, l = -1, r = -1; i != j; ) { if (i + l == 0) l = 1; if (i + l == j) { ans1 = 0; break; } i += l; if (j + r == i) { ans1 = 1; break; } j += r; } for (int i = a, j = b, l = -1, r = 1; i != j; ) { if (i + l == 0) l = 1; if (i + l == j) { ans2 = 0; break; } i += l; if (j + r > n) r = -1; if (j + r == i) { ans2 = 1; break; } j += r; } for (int i = a, j = b, l = 1, r = -1; i != j; ) { if (i + l == 0) l = 1; if (i + l == j) { ans3 = 0; break; } i += l; if (j + r > n) r = -1; if (j + r == i) { ans3 = 1; break; } j += r; } for (int i = a, j = b, l = 1, r = 1; i != j; ) { if (i + l == 0) l = 1; if (i + l == j) { ans4 = 0; break; } i += l; if (j + r > n) r = -1; if (j + r == i) { ans4 = 1; break; } j += r; } if ((ans1 && ans2) || (ans3 && ans4)) puts("Alice"); else puts("Borys"); }
B - Ice Rink Game
相当于一个数 $x$,每次进行一次 $\lfloor$$\dfrac{x}{a_i}$$\rfloor$ $\times a_i$,最后 $x$ 变成 $2$。
倒着进行这个过程,最小化答案的话一定是 $a_i$ 的整数倍,最大化答案的话一定是 $a_i$ 的整数倍加上 $a_i - 1$。
那么就倒着递推就好了。
#include <bits/stdc++.h> #define ll long long using namespace std; const int N = 1e5 + 7; ll a[N]; int n; int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%lld", &a[i]); } ll ans1 = 2, ans2 = 2; for (int i = n; i >= 1; i--) { ans1 = (ans1 - 1) / a[i] + 1, ans2 = ans2 / a[i]; if (ans1 > ans2) { puts("-1"); return 0; } ans1 *= a[i]; ans2 = ans2 * a[i] + a[i] - 1; } printf("%lld %lld\n", ans1, ans2); return 0; }
C - Median Sum
如果 $S_0$ 也被计入答案的话,那么中位数就肯定是所有答案里面的中位数。
因为对于每一种取法得到的答案 $ans$,肯定存在一个 $sum - ans$。
所有所有数的中位数即是答案的中位数。
除去 $S_0$,答案就在 $\lceil$$\dfrac{sum}{2}$$\rceil$ 往上第一个出现的数。
那么背包一下一个数是否出现。用bitset优化。
复杂度 $O(\dfrac{n ^ 3}{64})$
#include <bits/stdc++.h> using namespace std; const int N = 2000 * 2000 + 1; bitset<N> mask; int main() { int sum = 0; int n; scanf("%d", &n); mask.set(0); for (int i = 0, x; i < n; i++) { scanf("%d", &x); mask = (mask << x) | mask; sum += x; } sum++; sum /= 2; while (!mask.test(sum)) sum++; printf("%d\n", sum); }