• 4.1.4 Nim


    Problem description:

      有n堆石子,每堆各有ai颗石子。A和B轮流从非空的石子堆中取走至少一颗石子。A先取,取光所有石子的一方获胜。当双方都采用最佳策略时,谁会获胜?

      1<=n<=100000

      1<=ai<=10e9

    Input:

      n = 3

      a={ 1, 2 ,4}

    Output:

      A

    这个游戏是称为Nim的经典游戏,该游戏的策略称为了许多游戏的基础。要判断该游戏的胜负,只要用异或运算就好了。

      a1 ^ a2 ^ ……^ an !=0 -> 必胜态

      a1 ^ a2 ^ ……^ an  =0-> 必败态

    简单证明一下:

      首先从异或为零的状态取走至少一颗石子,异或就一定会变为非零。因此,可以证实必败态只能转移到必胜态。

      观察异或的二进制表示最高位的1,选取石子数的二进制表示对应位也为1的某堆石子。只要从中取走使得该位变为0,且其余异或中的1也反转的数量的石子,异或就可以变成零。

     若每次最多只能取k个怎么办呢? ai mod (k+1);

    在尼姆博奕中取完最后一颗糖的人为赢家,而取到最后一颗糖为输家的就是反尼姆博奕。

    反尼姆博奕的模型。在尼姆博奕中判断必胜局面的条件是所有堆石子数目相异或不等于0 。  而在反尼姆博奕中判断必胜局面的条件有两点,满足任意一点先手都能取胜,即必胜局面。   

                       1:各堆石子数目异或结果不等于0,且存在有石子数目大于1的石子堆。

                       2:各堆石子数目异或结果等于0,且所有石子堆数目全部为1。

    int N,A[MAX_N];
    
    void solve(){
        int x=0;
        for(int i=0;i<N;i++)
            x^=A[i];
        if(x!=0) puts("Alice");
        else puts("Bob");
    }
  • 相关阅读:
    boost库常用库介绍
    boost介绍
    vs2019+win10配置boost库
    交互式多媒体图书平台的设计与实现
    47.全排列 2
    46.全排列
    基于VSCode的C++编程语言的构建调试环境搭建指南
    码农的自我修养之必备技能 学习笔记
    工程化编程实战callback接口学习笔记
    Erlang模块inet翻译
  • 原文地址:https://www.cnblogs.com/astonc/p/9930372.html
Copyright © 2020-2023  润新知