Nim游戏

Posted Candy?

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nim游戏相关的知识,希望对你有一定的参考价值。

目前有3堆石子,每堆石子个数也是任意的,双方轮流从中取出石子,规则如下:1)每一步应取走至少一枚石子;每一步只能从某一堆中取走部分或全部石子;2)如果谁不能取谁就失败。


 

Bouton定理:

必败状态当且仅当x1^x2^x3==0

 


SG函数和SG定理:

对于任意状态x,SG(x)=mex(S),S是x后继状态中SG函数值集合,mex(S)表示不在S内的最小非负整数

 

有这样一个游戏,是多个游戏共同进行,每个游戏都执行到底时才算整个游戏结束,每次一个选手可以把一个游戏进行一步。

对于这样的游戏它的某状态的g(x)值,为每个子游戏的现在所处的状态的g(x)值抑或起来的结果


 

POJ2234

裸Nim游戏

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<0||c>9){if(c==-)f=-1;c=getchar();}
    while(c>=0&&c<=9){x=x*10+c-0;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");
    }
}

poj2975

Nim先手获胜方案数

找有多少堆数量大于其他堆异或的值,(取这堆后异或就是0了)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=1005;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<0||c>9){if(c==-)f=-1;c=getchar();}
    while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}
    return x*f;
}
int n,a[N];
int main(){
    while(scanf("%d",&n)!=EOF&&n){
        int s=0,ans=0;;
        for(int i=1;i<=n;i++) a[i]=read(),s^=a[i];
        if(s!=0) for(int i=1;i<=n;i++){
            int x=a[i],t=s^a[i];;
            if(x>t) ans++;
        }
        printf("%d\n",ans);
    }
}

 

以上是关于Nim游戏的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 3105 [CQOI2013]新Nim游戏 ——线性基

51nod 1069 Nim游戏 + BZOJ 1022: [SHOI2008]小约翰的游戏John(Nim游戏和Anti-Nim游戏)

Nim 游戏SG 函数游戏的和

博弈论Nim游戏:台阶集合拆分(AcWing)

BZOJ 1874: [BeiJing2009 WinterCamp]取石子游戏 [Nim游戏 SG函数]

LeetCode刷题292-简单-Nim游戏