HDU5754(博弈)

来源:互联网 发布:jessyline姐妹品牌js 编辑:程序博客网 时间:2024/06/05 00:30

意思是说四种棋子。问你随便一种棋子在一个n*m的格子上下棋是否能赢。

王:只能右、下和斜着走一格。他的必胜必败态可以找规律得到。

皇后:和王一样,但是能走任意步。

骑士:只能右、下,但是可以任意步。

马:走日。

分析:马的话,可能会出现平局,所以预处理出来每个点的必胜必败就好了。从1000*1000这个点往回跑。

王的话会发现当n和m都为奇数时先手赢不了。集体画3*3 5*5 4*4 画几个就明白了。

皇后的话无非就是两堆石子,可以分别取任意个,或者同时取相同。也可以预处理出sg函数。

骑士最简答。能一步走到头,。所以n==m时,无论你怎么走,对方都能和你走同样的步数在另一个方向。所以必败,反之你就可以走到必胜点,必胜。

#include<bits/stdc++.h>using namespace std;typedef long long ll;int dp[2010][2010];int jump[1010][1010];void sg(){    for(int i=1;i<=1000;i++)        for(int j=1;j<=1000;j++)            if(!dp[i][j])                for(int k=1;k<=1000;k++)                    dp[i+k][j+k]=dp[i+k][j]=dp[i][j+k]=1;}void init(){for(int i=1000;i>=3;i-=3)jump[i][i]=1,jump[i-1][i-2]=jump[i-2][i-1]=2;}int main(){    sg();init();    int t;scanf("%d",&t);    while(t--)    {        int op,n,m;scanf("%d%d%d",&op,&n,&m);        if(op==1){if(n&1&&m&1)printf("G\n");else printf("B\n");}        else if(op==2){if(n==m)printf("G\n");else printf("B\n");}        else if(op==3)        {            if(jump[n][m]==2)printf("B\n");            else if(jump[n][m]==1)printf("G\n");            else printf("D\n");        }        else        {            if(dp[n][m])printf("B\n");            else printf("G\n");        }    }    return 0;}


原创粉丝点击