算法 博弈论( 初级Nim游戏)

初级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;
}

版权声明:本文为Kerryliuyue原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。