台阶-Nim游戏
一、结论
如果奇数阶台阶的石子个数异或值不是零,则先手必胜。
如果奇数阶台阶的石子个数异或值是零, 则先手必败。
二、策略
-
如果对手是从奇数阶台阶拿石子
(a_1) ^ (a_3) ^ ... ^ (a_n=x)
(1) (x eq0) 一定存在某种方式,使得剩余石子的异或值变成零。
(2) (x=0) 不管怎么拿,剩余的石子异或值肯定不为零。
-
如果对手是从偶数阶台阶拿石子
我就把对手拿的个数,顺次放到下一级台阶上,比如,对手从(4)阶台阶拿(2)个石子到(3)阶台阶,我们就从(3)阶台阶,把这(2)个石子拿到(2)阶上。效果就是奇数阶台阶的石子个数没有改变。这样奇数阶台阶的异或值还是一样的,没有改变。
因此无论后手如何移动,先手总能通过操作把奇数异或为(0)的情况留给后手,当奇数台阶全为(0)时,只留下偶数台阶上有石子。
核心就是:先手总是把奇数台阶异或为(0)的状态留给对面,即总是将必败态交给对面。
因为偶数台阶上的石子要想移动到地面,必然需要经过偶数次移动,又因为奇数台阶全(0)的情况是留给后手的,因此先手总是可以将石子移动到地面,当将最后一个(堆)石子移动到地面时,后手无法操作,即后手失败。
因此如果先手时奇数台阶上的值的异或值为非(0),则先手必胜,反之必败!
三、代码
#include <bits/stdc++.h>
using namespace std;
int n;
int res;
int main() {
//优化输入
ios::sync_with_stdio(false);
cin >> n;
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
if (i % 2) res ^= x;
}
if (res) puts("Yes");
else puts("No");
return 0;
}