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]);
    }
    
  • 相关阅读:
    含字母的数字排序
    ci中简单实用的权限管理
    时间戳和日期转换
    prop
    定时器
    centos查看防火墙策略是firewall还是iptables
    centos上安装rabbitmq服务器
    springcloud微服务feign消费模式解决 com.netflix.client.ClientException: Load balancer does not have available server for client:xxx
    java正则去掉json字符串key的引号
    centos安装redis
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9409384.html
Copyright © 2011-2022 走看看