https://vjudge.net/contest/26587#overview
A - Calendar Game
题意:给定从 1900/1/1 到 2001/11/4 的任意一个日期,每次操作可以跳到明天或者下个月相同日期,先到 2001/11/4 的赢。
判断月份和日期之和的奇偶。
两种操作都会使得奇偶性改变,由于 11/3 是必胜态,所以如果和为偶数,则也是必胜。
有两个特殊的时间,9/30 和 11/30,这两个日期可以从奇数变到奇数,也就使得处于这两个日期可以使对面变为必败态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include<bits/stdc++.h> using namespace std; #define ll long long const int INF = 0x3f3f3f3f; const ll inf = 0x3f3f3f3f3f3f3f3f; const int N = 2e6 + 10; const ll mod = 1e9 + 7; int T; int main() { scanf("%d", &T); while (T--) { int y, m, d; scanf("%d%d%d", &y, &m, &d); if ((m + d) % 2 == 0 || m == 9 && d == 30 || m == 11 && d == 30)puts("YES"); else puts("NO"); } return 0; }
|
B - Euclid’s Game
题意:给定两个数,每次操作从大数中减去小数的倍数,要保证减完后不会有负。先使得操作完后小数变为 0 的人赢。
设大数为 a,小数为 b。
若 a%b=0 则先手胜。
若 a>2∗b,则可以操作为 (a%b,b),要知道每种状态都是确定必胜态或必败态。所以如果状态 (a%b,b) 是必败态,则先手操作到这个状态,否则操作到 (a%b+b,b),这样后手就只能操作到 (a%b,b),则先手无论怎样都是必胜。
若 a<2∗b,则只有一种操作,只能变为 (a−b,b),所以遇到这种情况就一直这样操作,直到出现上面两种状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include<bits/stdc++.h> using namespace std; #define ll long long const int INF = 0x3f3f3f3f; const ll inf = 0x3f3f3f3f3f3f3f3f; const int N = 2e6 + 10; const ll mod = 1e9 + 7; int a, b; int main() { while (scanf("%d%d", &a, &b) && a != 0) { if (a < b)swap(a, b); int flg = 1; while (1) { if (a%b == 0 || a > 2 * b)break; flg ^= 1; a -= b; swap(a, b); } puts(flg ? "Stan wins" : "Ollie wins"); } return 0; }
|
C - Play a game
题意:n*n 的网格,从一个角落开始,两人轮流移动到相邻四个格子,不能到待过的格子,不能动的输。
如上图,若 n⋅n 为偶数,则可以用几个 2⋅1 的区域覆盖,不论后手移动到哪里,先手都可以移动到当前点所在区域中另一个格子去。
若为奇数,则区域覆盖除了起点外的其它点,无论先手移动到哪里,后手也都可以到另一个点。
也可以说这样走总可以走遍所有格子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include<bits/stdc++.h> using namespace std; #define ll long long const int INF = 0x3f3f3f3f; const ll inf = 0x3f3f3f3f3f3f3f3f; const int N = 2e6 + 10; const ll mod = 1e9 + 7; int n; int main() { while (scanf("%d", &n) && n != 0) { if ((n*n) & 1)puts("ailyanlu"); else puts("8600"); } return 0; }
|