zoukankan      html  css  js  c++  java
  • 【数论学习笔记】 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
    ");
            return 0;
        }
        for(int i=1;i<=n;i++){
            if((c^a[i])<a[i]){
                printf("%d %d
    ",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;
    }
  • 相关阅读:
    最小花费
    LOJ10090
    LOJ2436
    loj10087
    LOJ2632
    LOJ10021 Addition Chains
    LOJ10019生日蛋糕
    loj10018数的划分
    LOJ10015扩散
    loj10014数列分段二
  • 原文地址:https://www.cnblogs.com/ChrisKKK/p/10874700.html
Copyright © 2011-2022 走看看