简单转化之后(可以参考官方题解),变成了:网格中有个阶梯形状的轮廓线,棋子从 $(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 | int main() { |