题目描述
甲,乙两个人玩Nim取石子游戏。
nim游戏的规则是这样的:地上有n堆石子(每堆石子数量小于10000),每人每次可从任意一堆石子里取出任意多枚石子扔掉,可以取完,不能不取。每次只能从一堆里取。最后没石子可取的人就输了。假如甲是先手,且告诉你这n堆石子的数量,他想知道是否存在先手必胜的策略。
输入输出格式
输入格式:
第一行一个整数T<=10,表示有T组数据
接下来每两行是一组数据,第一行一个整数n,表示有n堆石子,n<=10000;
第二行有n个数,表示每一堆石子的数量
输出格式:
共T行,如果对于这组数据存在先手必胜策略则输出"Yes",否则输出"No",不包含引号,每个单词一行。
输入输出样例
输入样例#1: 复制
2 2 1 1 2 1 0
输出样例#1: 复制
No Yes
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
cin>>t;
while(t--){
int n;
while(cin>>n){
int flag=0;
for(int i=0;i<n;i++){
int a;
cin>>a;
flag^=a;
}
if(!flag)
cout<<"No"<<endl;
else
cout<<"Yes"<<endl;
}
}
return 0;
}
过程
博弈问题。。。emmm以后完全明白之后写个详细点的。
下面的是做这类题的模板
1.把原游戏分解成多个独立的子游戏,则原游戏的SG函数值是它的所有子游戏的SG函数值的异或。
- 即sg(G)=sg(G1)^sg(G2)^...^sg(Gn)。
2.分别考虑没一个子游戏,计算其SG值。
- SG值的计算方法:(重点)
- 可选步数为1~m的连续整数,直接取模即可,SG(x) = x % (m+1);
- 可选步数为任意步,SG(x) = x;
- 可选步数为一系列不连续的数,用模板计算。
关于SG(x) = x % (m+1);和SG(x) = x;