【模板】nim游戏

题目描述

甲,乙两个人玩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. 可选步数为1~m的连续整数,直接取模即可,SG(x) = x % (m+1);
    2. 可选步数为任意步,SG(x) = x;
    3. 可选步数为一系列不连续的数,用模板计算。

关于SG(x) = x % (m+1);和SG(x) = x;

猜你喜欢

转载自blog.csdn.net/SuBaiACCa/article/details/83755523