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=0a\%b=0 则先手胜。

a>2ba>2*b,则可以操作为 (a%b,b)(a\%b,b),要知道每种状态都是确定必胜态或必败态。所以如果状态 (a%b,b)(a\%b,b) 是必败态,则先手操作到这个状态,否则操作到 (a%b+b,b)(a\%b+b,b),这样后手就只能操作到 (a%b,b)(a\%b,b),则先手无论怎样都是必胜。

a<2ba<2*b,则只有一种操作,只能变为 (ab,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 的网格,从一个角落开始,两人轮流移动到相邻四个格子,不能到待过的格子,不能动的输。

如上图,若 nnn\cdot n 为偶数,则可以用几个 212\cdot 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;
}