zoukankan      html  css  js  c++  java
  • 阶梯博弈(历届试题 高僧斗法 )

     

     我们可以将人从前往后两两配对,在同一对人中,如果对手移动后一个人,你总能移动前一个相同的步数,

    所以一对人的后一个人与后面一对人的前一个人有多少台阶是没有影响的。

    所以只要考虑同一对人之间有多少台阶就行了,这样就转化为了Nim游戏。

    如图: a与b配对, c与d配对 ,那么b与c之间的台阶是没有影响的,无论b怎么移动,a总能够移动相同的步数

    如果该Nim游戏为必胜,那么我们只要移动配对人中的前一人就好了,如果对手想要破坏这种Nim游戏,即他想移动配对中的后一人,那么我们可以移动前一对的后一个人

    使得依然保持Nim游戏的局势。

    如果Nim游戏必败,那么先手者可能想破坏Nim游戏,那么后手者按照刚才的方式保持Nim游戏即可。

     1 #include <stdio.h>
     2 #include <string.h>
     3 const int N = 100 + 10;
     4 int a[N],b[N];
     5 int main()
     6 {
     7     int n = 0,i,j,k,sum = 0;
     8     while(scanf("%d",&a[n])!=EOF)
     9         n++;
    10     for(i=1; i<n; ++i)
    11         b[i-1] = a[i] - a[i-1] - 1;
    12     for(i=0; i<n-1; i+=2)
    13         sum ^= b[i];
    14     if(sum==0)
    15         printf("-1
    ");
    16     else
    17     {
    18         //枚举第i个人移动j步,使得剩下的局面异或等于0,
    19         for(i=0; i<n-1; ++i)
    20             for(j=1; a[i]+j<a[i+1]; ++j)
    21             {
    22                 
    23                 b[i] -= j;
    24                 if(i!=0)
    25                     b[i-1] += j;
    26                 
    27                 sum = 0;
    28                 for(k=0; k<n-1; k+=2)
    29                     sum ^= b[k];
    30                 if(sum==0)
    31                 {
    32                     printf("%d %d
    ",a[i],a[i]+j);
    33                     break;
    34                 }
    35                 b[i] += j;
    36                 if(i!=0)
    37                     b[i-1] -= j;
    38                 
    39             }
    40     }
    41     return 0;
    42 }

      

  • 相关阅读:
    kali-linux镜像下载
    清除数据库所有表
    家庭医生项目进展
    2020年度发展规划的要点
    Sql Server数据类型
    window server2012R2激活
    C#介绍
    WebApi自动接口文档Swagger汉化和添加Token验证
    SQL Server 数据库内部版本号
    用户定义表类型
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4367904.html
Copyright © 2011-2022 走看看