0%

AGC002E Candy Piles

简单转化之后(可以参考官方题解),变成了:网格中有个阶梯形状的轮廓线,棋子从 $(0,0)$ 开始走,每次可以往左走或者往上走,走到边界的那一步的操作者输(即,边界上的点是必胜态)。

可以证明,如果 $(x+1,y+1)$ 不在边界上,那么 $(x,y)$ 的胜负状态和 $(x+1,y+1)$ 的胜负状态相同。

证明:

1)可以从 $(x+1,y+1)$ 为必败态推出 $(x,y)$ 为必败态:如果 $(x+1,y+1)$ 必败,那么 $(x,y+1), (x+1,y)$ 都是必胜态,那么 $(x,y)$ 就必败。

2)可以从 $(x+1,y+1), (x+2,y+2)$ 是必胜态推出 $(x,y)$ 是必胜态:$(x+3,y+2)$ 和 $(x+2,y+3)$ 中至少有一个是必败态,我们假设 $(x+3,y+2)$ 是必败态,可以推出:

\ x x+1 x+2 x+3
y+2 * * 1 0
y+1 * 1 0 (b) 1 (a)
y 1 (e) 0 (d) 1 (c) *

其中,* 表示不确定,斜体表示已知的条件,(a) ~ (e) 代表推理的顺序。

对于 $(x+2,y+3)$ 必败的情况可以同理证明。

代码实现:从 $(0,0)$ 出发往右上走,直到下一步会碰到边界,然后算出其上方和右边的格子的状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main() {
rd(n);
for(int i=0;i<n;++i) rd(a[i]);
sort(a,a+n,greater<int>());
int x=0,y=0;
while(y+1<a[x+1]) x++,y++;

int t1=!((a[x]-(y+1))&1);
int r=x; while(y<a[r+1]) r++;
int t2=!((r+1-(x+1))&1);

if(!(t1&t2)) printf("First");
else printf("Second");
return 0;
}