zoukankan      html  css  js  c++  java
  • 取火柴游戏||Nim博弈

    好久之前看的sg函数了

    好像就记住一个nim博弈qwq

    第一次啊看的时候很迷,现在感觉可以了qwq


    首先我们来看一个其他的游戏。(以下游戏只有两个人参与,且足够聪明)

    两个人在一张圆形的桌子上放等大的盘子,最后一个无法放盘子的人输掉比赛

    很显然,先手必胜。

    为什么? 第一个人可以将盘子放在桌子的中心。

    然后只要第二个人可以放置盘子,我们就在其中心对称的位置上放盘子。

    如此,只要后手可以放,我先手就一定能放

    可以看出,有时候如果处于先手必胜的状态时,模仿对手的策略不妨是个好方法。这可以保证如果游戏可以进行下去的话,先手就一定能进行下去。


    我们再来看一个更nim游戏的弱化版

    有两个火柴堆,每堆的火柴数不一定相同,每次一个人只能从一堆中选取若干个火柴并取走。没有火柴可取的人输

    好像这和上个题没有什么关系qwq

    我们假设两个火柴堆的数目都相同。那么肯定是先手必输

    为什么?因为后手总可以从另一堆中取的和先手上一次取得一样的火柴。

    只要先手可以取,后手就可以取。

    所有该游戏的判定条件是,若两堆相等,先手必输,否则,先手必胜,先手总可以将两堆取成一样多


    先手必胜时总有一种策略可以转移到后手必败
    后手必败总是会转移到先手必胜

    好像大佬如此说过


    然后我们看van♂整版nim

    P1247 取火柴游戏

    先说结论,若所有火柴堆异或起来的值为0的话,先手必败,否则先手必胜

    啥?mengbi qwq

    (ノ`⊿´)ノ为什么和异或结合起来的啊喂

    这是得益于毒瘤的二进制和更毒瘤的异或

    异或有一个特殊的规律,就是一堆数异或时,若在同一个二进制位上1的个数是偶数,那么这一位异或起来以后是0,否则为1

    二进制的话就是可以使用0/1表示所有数字


    我们来看上一个游戏,我们将这两堆的剩余的火柴数转变成二进制。

    发现我们先手取走一个数,就是改变其二进制为上的1的个数(只考虑奇偶性),而后手再去取的话就是将其奇偶性再变回来


    然后我们再回去看为什么异或和是0时先手必输,因为先手拿走了某些火柴时,我们可以根据其拿走火柴的二进制表示,在其他一堆中拿走一些一些数字,使得其异或和重新为0;

    怎么搞呢? 我们可以拿走一些数,也就是减某一个数,使得先手拿完后,(啰嗦警告)

    所有堆中的每个二进制上的一的个数的和,我们总可以通过加减一个数,达到在某一个二进制位的1的个数进行加一or减一的效果

    使得某一位二进制上的1的个数变为偶数。

    从而使得游戏又恢复到了一开始的局面

    end......

    sg函数好像也是这个思想qwq

    此题代码

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<iostream>
    using std::sort;
    const int maxn=501000;
    int data[maxn];
    int main()
    {
    	int n;
    	scanf("%d",&n);
    	int x=0;
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&data[i]);
    		x^=data[i];
    	}
    	if(x==0)
    	{
    		printf("lose");
    		return 0;
    	}
    	for(int i=1;i<=n;i++)
    		if((data[i]^x)<=data[i])
    		{
    			printf("%d %d
    ",data[i]-(data[i]^x),i);
    			data[i]^=x;
    			break;
    		}
    	for(int i=1;i<=n;i++)
    		printf("%d ",data[i]);
    }
    
  • 相关阅读:
    learning scala view collection
    scala
    learning scala dependency injection
    learning scala implicit class
    learning scala type alise
    learning scala PartialFunction
    learning scala Function Recursive Tail Call
    learning scala Function Composition andThen
    System.Threading.Interlocked.CompareChange使用
    System.Threading.Monitor的使用
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9409384.html
Copyright © 2011-2022 走看看