【数论学习笔记】 NIM游戏

博弈论的内容。

游戏规则:

  地上有n堆石子,每人每次可从任意一堆石子里取出任意多枚石子扔掉,可以取完,不能不取。

  每次只能从一堆里取。最后没石子可取的人就输了。

先手是先操作的人。

定理:先手必胜 当且仅当 A1 xor A2 xor A3……!= 0。

证明:当所有物品都取光。明显为A1 xor A2 xor A3……= 0。

   如果A1 xor A2 xor A3……= x != 0。假设最高位1在第k位。

   必然有至少一堆石子Ai 第k为1。

   Ai xor x < x。(第k位为0了。)

   这样就从Ai 中取出石子,使得新的序列A1 xor A2 xor A3……= 0。后手必定无法取。(先手可以一直和后手取一样多的石子维护这个序列异或等于零。)

例题:

  luogu:P1247:https://www.luogu.org/problemnew/show/P1247

      P2197:https://www.luogu.org/problemnew/show/P2197

  P1247代码如下。

  

#include<bits/stdc++.h>
using namespace std;
int n,c=0;
int a[500005];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        c^=a[i];
    }
    if(c==0){
        printf("lose\n");
        return 0;
    }
    for(int i=1;i<=n;i++){
        if((c^a[i])<a[i]){
            printf("%d %d\n",a[i]-(c^a[i]),i);
            for(int j=1; j<=n; j++)
                if(j!=i)
                    printf("%d ",a[j]);
                else
                    printf("%d ",c^a[i]);
            break;
        }
    }
    // while(1);
    return 0;
}

 

posted @ 2019-05-16 11:43  ChrisKKK  阅读(180)  评论(0编辑  收藏  举报