• HDU 5754 Life Winner Bo 2016多校第三场1003


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5754

    题意:给你一个n*m大小的棋盘,分别以国际象棋的国王、战车、骑士和皇后的走法从(1,1)走到(n,m),而且只能向右或者向下走,问谁有必胜的策略或者是两者平局。

    题解:无论是哪一种移动,都可以注意到,如果从起点到某一个点有必胜的策略,那么再以必胜点作为起点可以走到下一个必胜点,也就是以小见大。

       一、对于王的走法,可以注意到3*3大小的棋盘,从(1,1)到(3,3)后手是有必胜的策略的,对于NM更大的情况,我们把横坐标每隔3、纵坐标每隔3的点都画出来,这些点都是符合后手胜的。因为无论先手怎么移动,后手都能重新移动到这些格子,直到到了终点)如果初始点不在这些点上,就必然是先手胜。因为先手可以立刻移动到上述的点。

       二、对于车的走法,注意到,如果目前的位置距离终点的x和y坐标差相等,一定是后手胜。(因为先手只能向下或者向右走一段路;无论他往哪里走,后手往另一维走相同的步数,依然保持这一样一种状态。)反之,先手必然能走到一处相等的位置,转化为上述问题,所以一定是先手胜。

       三、马的走法,在大多数情况下都是平局。在模3域下,某些地方会存在先后手赢。画图找规律。

       四、皇后的走法最为复杂,不过其实也就是一个威佐夫博弈。

       关于威佐夫博弈:http://baike.baidu.com/link?url=Xf_NMvP2GFcr93BAmCLsTqY6ULiseus-TLg0dgG_1yx1C-bzt0pSQAFOt0jMb6WvGwd9S_xIj6ZCtBIc0ygotbc9IglMjGcwHHD8nsohR-bIf5yNzG35AHD5xbhrhkSi)。

       我们可以将问题转化为:“有两堆石子,每次可以在一堆里取任意(非空)颗(相当于是车的走法),或者在两堆里取相同(非空)颗(相当于是象的走法),取到最后一颗石子的人获胜,问先后手谁有必胜策略。”为什么说是威佐夫博弈呢。

       其实仔细想一想就会明白这个走法产生的局面(画图更为清楚),先手从(1,1)开始走,那么第一步他可以到达任意一个x=1(或y=1,两者对称)的局面,那么我们看x=2的时候,(2,1)(2,2)是先手在第一步能到达的。然而(2,3)是后手的必胜点。那么根据前面所说我们在从(2,3)作为起点开始推可以知道,从(2,3)开始的第一步是可以到达坐标中带有2或者3的任意点(别忘了(3,2)与(2,3)等价),也就是说后手的下一个必胜点必定是从x=4(或y=4)开始的(而且x=4时必定有后手的必胜点),这里又是为什么呢?很简单,就是因为从(2,3)开始走,所有坐标中带有2或者3的所有局面先手都可以到达,而且先手只能去到坐标中带有4的部分局面。如图(把所有坐标+1即可得到本题局面):

        由此我们可以推知,皇后的走法,后手必胜点就是威佐夫博弈中的奇异局势,打表即可(也有必胜点的公式求法:一个奇异局势(ak,bk)为:ak =[k(1+√5)/2],bk= ak + k (k=0,1,2,...n 方括号表示取整函数)

        这是本人对威佐夫博弈的一点点理解,还不够深入,欢迎吐槽!。

    代码如下:

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <cmath>
     7 using namespace std;
     8 
     9 const double phi=(1+sqrt(5.0))/2.0;
    10 int t,ty;
    11 int n,m;
    12 int g[1005][1005];
    13 int f[1005];
    14 int vis[2][2005];
    15 
    16 int main()
    17 {
    18     int x,y;
    19     for(int i=1;;i++)
    20     {
    21         x=phi*i;
    22         y=x+i;
    23         if(y>1000)
    24             break;
    25         f[x]=y;
    26     }
    27     scanf("%d",&t);
    28     while(t--)
    29     {
    30         scanf("%d%d%d",&ty,&n,&m);
    31         if(ty==1)
    32         {
    33             if(n%2&&m%2)
    34                 puts("G");
    35             else
    36                 puts("B");
    37             continue;
    38         }
    39         else if(ty==2)
    40         {
    41             if(n==m)
    42                 puts("G");
    43             else
    44                 puts("B");
    45             continue;
    46         }
    47         else if(ty==3)
    48         {
    49             if(n==m&&n%3==1)
    50                 puts("G");
    51             else if(max(n,m)%3==0&&max(n,m)-min(n,m)==1)
    52                 puts("B");
    53             else
    54                 puts("D");
    55         }
    56         else
    57         {
    58             n--,m--;
    59             if(n>m) swap(n,m);
    60             if(f[n]==m)
    61                 puts("G");
    62             else
    63                 puts("B");
    64         }
    65     }
    66     return 0;
    67 } 
  • 相关阅读:
    机器学习:以分析红酒口感为例说明交叉验证的套索模型
    机器学习:分类算法性能指标之ROC曲线
    机器学习:最小二乘法实际应用的一个完整例子
    机器学习:Python中如何使用支持向量机(SVM)算法
    机器学习:python中如何使用朴素贝叶斯算法
    机器学习:Python实现lms中的学习率的退火算法
    机器学习:Python实现最小均方算法(lms)
    @Autowired 与@Resource选择(治好你的强迫症)
    @Resource 进行注入bean的过程
    @Autowired 进行注入bean的过程
  • 原文地址:https://www.cnblogs.com/zhuyutian/p/5790765.html
Copyright © 2020-2023  润新知