目前有3堆石子,每堆石子个数也是任意的,双方轮流从中取出石子,规则如下:1)每一步应取走至少一枚石子;每一步只能从某一堆中取走部分或全部石子;2)如果谁不能取谁就失败。
Bouton定理:
必败状态当且仅当x1^x2^x3==0
SG函数和SG定理:
对于任意状态x,SG(x)=mex(S),S是x后继状态中SG函数值集合,mex(S)表示不在S内的最小非负整数
SG(x)=0当且仅当x为P
有这样一个游戏,是多个游戏共同进行,每个游戏都执行到底时才算整个游戏结束,每次一个选手可以把一个游戏进行一步。
对于这样的游戏它的某状态的g(x)值,为每个子游戏的现在所处的状态的g(x)值xor起来的结果
裸Nim游戏
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,a;
int main(){
while(scanf("%d",&n)!=EOF){
a=read();n--;
while(n--) a^=read();
if(a) puts("Yes");
else puts("No");
}
}
Nim先手获胜方案数
找有多少堆数量大于其他堆异或的值,(取这堆后异或就是0了)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,a[N];
int main(){
while(scanf("%d",&n)!=EOF&&n){
int s=,ans=;;
for(int i=;i<=n;i++) a[i]=read(),s^=a[i];
if(s!=) for(int i=;i<=n;i++){
int x=a[i],t=s^a[i];;
if(x>t) ans++;
}
printf("%d\n",ans);
}
}