• (反NIM)


    题目大意是和普通的NIM游戏一样,但是却是取到最后一个是输的,天真的以为就是反过来,其实并不是这样的

    结论

    先手必胜的条件为 
    ①:所有堆的石子数均=1,且有偶数堆。 
    ②:至少有一个堆的石子数>1,且石子堆的异或和≠0。

    证明

    一、当所有堆的石子数均为1时 
         (1):石子异或和(t)=0,即有偶数堆。此时显然先手必胜。 
         (2):t≠0,即有奇数堆。此时显然先手必败。 
    二、当有一堆的石子数>1时,显然t≠0 
         (1):总共有奇数堆石子,此时把>1的那堆取至1个石子,此时便转化为一.(2),先手必胜。 
         (2):总共有偶数堆石子,此时把>1的那堆取完,同样转化为一.(2),先手必胜。 
    三、当有两堆及以上的石子数>1时 
         (1):t=0,那么可能转化为以下两个子状态: 
                     ①:至少两堆及以上的石子数>1且t≠0,即转为三.(2)。 
                     ②:至少一堆石子数>1,由二可知此时必胜。 
         (2):t≠0,根据Nim游戏的证明,可以得到总有一种方法转化为三.(1)状态。 
    观察三我们发现,三.(2)能把三.(1)扔给对面,而对面只能扔给你三.(2)或必胜态。所以当三.(2)时先手必胜。

    综上,所有堆的石子数均=1且t=0/至少有一个堆的石子数>1且t≠0时,先手必胜。

    参考HDU2509

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<math.h>
    int main()
    {
        int ts;//确定是T态还是S态 
        int n;
        int i,j;
        int m[100];
        int Nuheap;//充裕堆的个数     
        while(scanf("%d",&n)!=EOF)
        {
               Nuheap=0;
               ts=0;
               for(i=1;i<=n;i++)
               {
                      scanf("%d",&m[i]);
                      if(m[i]>=2)
                      Nuheap++;
                      ts^=m[i];
               }
               if((ts==0&&Nuheap>=2)||(ts!=0&&Nuheap==0))    //我们知道 如果当前是T2态,那么只能转变成S1或者S2态,此时对手应用正确的方法必胜,所以这个是必败点,同理S0态也是必败点;
                {
                   printf("No
    ");
                }
                else
                {
                    printf("Yes
    ");
                }
          }
          return 0;
    }
  • 相关阅读:
    SVN的安装和使用手册2
    svn安装
    【1】第一篇 Postman的初级使用之设置环境快速切换生成环境与测试环境
    【4】Postman之Tests(断言)
    RIDE,如何指定report,log,output的存放位置
    python启动robotframework-ride失败,解决方案
    Python安装第三库超时的解决方法
    python 识别登陆验证码图片(完整代码)
    代码-字典
    Python数据分析入门
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/9559256.html
Copyright © 2020-2023  润新知