初级Nim游戏
给定n堆石子,两位玩家轮流操作,每次操作可以从任意一堆石子中拿走任意数量的石子(可以拿完,但不能不拿),最后无法进行操作的人视为失败。
问如果两人都采用最优策略,先手是否必胜。
输入格式
第一行包含整数n。
第二行包含n个数字,其中第 i 个数字表示第 i 堆石子的数量。
输出格式
如果先手方必胜,则输出“Yes”。
否则,输出“No”。
数据范围
1≤n≤10^5,
1≤每堆石子数≤10^9
输入样例:
2
2 3
输出样例:
Yes
异或符号是⊕.
1⊕1=0
0⊕0=0
1⊕0=1
先手必胜和先手必败
以取石子游戏为例,如果一个玩家面对的是没有石子的状态,那么他就失败了,也就是说「没有石子」是先手必败的状态。
如果一个状态能转移到一个先手必败的状态,那么当前的先手一定会转移到先手必败的状态,让对方(也就是下一步的先手)面对这个必败的状态。因此,如果一个状态能转移到至少一个先手必败的状态,那么这个状态就是先手必胜的。否则,转移到的所有状态都是先手必胜,那么这个状态就是先手必败的。
根据结论,关键就是求异或之后的结果res是0还是1
#include<iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int res=0;//记录异或之后的结果
for(int i=0;i<n;i++)
{
int x;
scanf("%d",&x);
res^=x;
}
if(res==0)
printf("No");
else printf("Yes");
return 0;
}