巴什博弈(hdu1846,hdu2147,hdu2149)

最简单的巴什模型是:

只有一堆n个物品,两个人轮流从这堆物品中取物,规

定每次至少取一个,最多取m个。最后取光者得胜。

很容易想出策略,如果n%(m+1)==s(s!=0),那么我先取出s个,后面他任意取出1~m中的一个数k,我就取出m+1-k这样保证每一次和为m+1,这样一定是我最后取出。

所以若n%(m+1)==s那么先出的赢,反之若n%(m+1)==0,那么先取得必输.

更普遍的现象是:

有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取p个,最多取q个.最后取光者得胜.

 n = (m+1)r+s , (r为任意自然数,s≤m), 即n%(p+q) != 0, 则先取者肯定获胜(默认最后一个取的为win)

相应的练习hdu1846,hdu2147,hdu2149

//hdu1846直接套公式
#include <stdio.h>
 int main()
 {
     int T,n,m;
     scanf("%d",&T);
     while(T--)
     {
         scanf("%d%d",&n,&m);
         if (n%(m+1)==0)//先手必输
          printf("second\n");
         else
            printf("first\n");
      }
      return 0;
 }
//hdu2147有一个游戏,在一个n*m的矩阵中起始位置是(1,m),走到终止位置(n,1);游戏规则是只能向左,向下,左下方向走,想走到终点的为获胜者。
#include <stdio.h>
 int main()
 {
     int n,m;
     while((scanf("%d%d",&n,&m)==2)&&(n||m))
     {
         if ((n%2==0)||(m%2==0))
            printf("Wonderful!\n");
         else
            printf("What a pity!\n");
     }
     return 0;
 }
 
//hdu2149公式,注意特殊情况
#include <stdio.h>
 int main()
 {
     int i,n,m;
     while(scanf("%d%d",&m,&n)==2)
     {
          if (m<n)
          {
                printf("%d",m);
                for (i=m+1;i<=n;i++)
                printf(" %d",i);
                printf("\n");
          }
          else
          if (m%(n+1)==0)
            printf("none\n");
         else
            printf("%d\n",m%(n+1));

     }
     return 0;
 }









你可能感兴趣的:(巴什博弈(hdu1846,hdu2147,hdu2149))