HDU_5754 Life Winner Bo

Life Winner Bo

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2139    Accepted Submission(s): 779


Problem Description
Bo is a "Life Winner".He likes playing chessboard games with his girlfriend G.

The size of the chessboard is  N×M .The top left corner is numbered (1,1)  and the lower right corner is numberd  (N,M) .

For each game,Bo and G take turns moving a chesspiece(Bo first).At first,the chesspiece is located at  (1,1) .And the winner is the person who first moves the chesspiece to  (N,M) .At one point,if the chess can't be moved and it isn't located at  (N,M) ,they end in a draw.

In general,the chesspiece can only be moved right or down.Formally,suppose it is located at  (x,y) ,it can be moved to the next point  (x,y)  only if  xx  and  yy .Also it can't be moved to the outside of chessboard.

Besides,There are four kinds of chess(They have movement rules respectively).

1.king.

2.rook(castle).

3.knight.

4.queen.

(The movement rule is as same as the chess.)

For each type of chess,you should find out that who will win the game if they both play in an optimal strategy.

Print the winner's name("B" or "G") or "D" if nobody wins the game.
 

Input
In the first line,there is a number  T  as a case number.

In the next  T  lines,there are three numbers type, N  and  M .

"type" means the kind of the chess.

T1000,2N,M1000,1type4
 

Output
For each question,print the answer.
 

Sample Input
      
      
4 1 5 5 2 5 5 3 5 5 4 5 5
 

Sample Output
      
      
G G D B
 

Author
绍兴一中
 

Source

 

题目大意:

   有一个n*m的棋盘,如果能从左上角走到右下角就算赢,B为先手,G为后手,有四种棋子,分别是国王、车、马和皇后

先介绍一下四种棋子的移动规则:

  • king:可走到周围的8个格子.
    当前位置(i,j)的状态由(i+1,j) (i,j+1) (i+1,j+1)确定.
  • rook:可以横着竖着走任意个格子.
    简单推理可得只有i==j时必败,其余必胜.
  • knight:走"L"型路线.
    当前位置(i,j)的状态由(i+2,j+1) (i+1,j+2)确定.
  • queen:横竖斜走任意格子.
    对于每个必败态,将可到达的横竖斜格子全部置成必胜态.

题目要求不能移动且没有到右下角时为平手,那么只有knight可能出现平手,即走到边界时不能再移动.
对于当前位置,如果能走到必败态,那么一定是必胜态;若不能走到必败态,那么如果能走到平局位置,则一定是平局。

* 对于第一种情况:先分析九个格子的情况,右下角为终点,然后依次往外找,能到必败态的一定是必胜态,只能到必胜态的一定是必败态。然后

可以发现当n%2 == 0 || m%2 == 0时,先手必胜,否则,先手必败。

* 对于第二种情况:当n==m(正方形)时先手必败,因为无论先手怎么走后手都能走到对角线上,同理当n!=m时先手直接走到对角线上,和前面

一样,此时先手必胜。

* 对于第三种情况:只有这种情况会走不到终点而出现平局,先考虑一定能走到终点的情况,往下走相当于往右走一个再往下走两个,往右走相当

与往右走两格再往下走一格。假设往右和往下走的步数分别为x, y则必有:

{2x+y=m12y+x=n1
解得: : x=2mn13,y=2nm13 ,可得总步数为 m+n23 ,故当m+n-2是3的倍数时一定能走到终点,再考虑当x==y时,先手必败,当

abs(x-y)==1时先手必胜,当abs(x-y)>1时,总有一方可以走到边界制造平局。

* 对于第四种情况,将往右和往下分堆,则斜着走相当于从两堆中取石子,往右或者往下走分别代表从一堆中取和从另一堆中取,即为威左夫博弈

代码如下:

#include <bits/stdc++.h>

using namespace std;

int main()
{
        int t;
        scanf("%d", &t);
        while(t--)
        {
                int k, n, m;
                scanf("%d%d%d", &k, &n, &m);
                if(k == 1)
                {
                        if(m % 2 == 0 || n % 2 == 0)
                        {
                                puts("B");
                        }
                        else puts("G");
                }
                else if(k == 2)
                {
                        if(n == m)
                                puts("G");
                        else puts("B");
                }
                else if(k == 3)
                {
                        if((n+m-2) % 3) //走不到终点
                                puts("D");
                        else
                        {
                                if(abs((2*m-n-1)/3 - (2*n-m-1)/3) == 0)
                                        puts("G");
                                else if(abs((2*m-n-1)/3 - (2*n-m-1)/3) == 1)
                                        puts("B");
                                else puts("D");
                        }
                }
                else
                {
                        n--;
                        m--;
                        if(n < m) //n>m
                                swap(n, m);
                        int k = n-m;
                        n = k*(1+sqrt(5)) / 2.0;
                        if(n == m)
                                puts("G");
                        else puts("B");
                }
        }
        return 0;
}



(m+n2) 的时候,x


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值