尼姆博奕(Nimm Game)--为什么异或能等于0是奇异局势

尼姆博奕(Nimm Game):有三堆各若干个物品,两个人轮流从某一堆取任意多的物品,规定每次至少取一个,多者不限,最后取光者得胜。

    首先(0,0,0)显然是奇异局势,无论谁面对奇异局势,都必然失败。第二种奇异局势是(0,n,n),只要与对手拿走一样多的物品,最后都将导致(0,0,0)。仔细分析一下,(1,2,3)也是奇异局势,无论对手如何拿,接下来都可以变为(0,n,n)的情形。

    计算机算法里面有一种叫做按位模2加,也叫做异或的运算,我们用符号(+)表示这种运算。这种运算和一般加法不同的一点是1+1=0。先看(1,2,3)的按位模2加的结果:

1 =二进制01
2 =二进制10
3 =二进制11 (+)
———————
0 =二进制00 (注意不进位)

    对于奇异局势(0,n,n)也一样,结果也是0。

    任何奇异局势(a,b,c)都有a(+)b(+)c =0。

本文重点:为什么异或能等于0是奇异局势

就拿:1 =二进制01
           2 =二进制10
           3 =二进制11             做例子

1^2^3=0:第一:说明了每个位置的1的个数是偶数

                 第二:每堆石头你可以任意取几个,那就相当于2可以分成两个数量为1的堆,3可以分成1+1+1,或1+2

                 第三:这是奇异局势,每次取石头,就相当于取其中某几个1,例如:当玩家A在数量为3的这一堆里取出两个石头,

                            这时3(11)从11变成了1(01),被取走了第二个位置的那个1,这是玩家B(够聪明)就相应的取走2中第二                             个位置的1,这样取到最后,玩家B就拿到最后的石头(赢了),

                           所以只要保持这些数字的二进制相对于的1数量是偶数,就是奇异局势,这样对面怎么取(第三点这种理解的取                             法),就能让对面保持奇异局势(必败局势);

                 

记住:任意取数量石头就相当于你可以拆堆,即取任意个1

 

#include <cstdio>
using namespace std;
int main(){
    int m,ans,n;
    while(~scanf("%d",&m)){                           
        n=ans=0;
        while(m--)              //有m堆石头
            scanf("%d",&n),ans^=n,printf("ans=%d\n",ans);      //
        if(ans)printf("Yes\n");    //如果异或结果不为0,且我先拿,我赢
        else printf("No\n");       //我面临奇异局势
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章