HDU 5754 Life Winner Bo 2016 多校合练 Contest 3


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
 



题意:
题意很简单,就是四个棋子国王,皇后,马和车,问你从(1,1)点谁能先下到(n,m)点。
首先是国王:国王可以直走和斜走一格。那么与他相邻的格子就是(1,2)(2,2)(2,1)为先手点,可以递归,求只能被先手点走一次走到的点为后手点。这样得出规律当n,m都是级数为后手点。
其次是车:车可以走直线,那么(1,n)与(n,1)都是先手点,那么(2,2)必为后手点。这样通过递归思想,所有(n,n)点,都是后手点。
然后是马。通过达标可以发现,马的位置是固定点,分成先手行与后手行。有一个坑就是如果这个点虽然可以走到且甲赢,但是如果乙不想让你走到,在某些点是可以做到的。这样就发现,只有在角平分线附近的一个或两个点是不受对方影响的两个点。这就得出先手点与后手点。
最后是王后,通过打表,每次遍历先手点,求i+j最小的点设置成后手点,再次遍历,得到王后表。
这个题只让打一个表。

#include<iostream>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;
int Knight[1010][1010];

void Build( int x, int y )
{
    if( x > 1000 || y > 1000 )
        return;
    int X, Y;
    bool fa = 0;
    int min = 2000;
    for( int i = x + 1; i < 1001; i++ )
    {
        for( int j = y + 1; j < 1001; j++ )
        {
            if( Knight[i][j] == 0 )
            {
                if( min > i + j )
                {
                    X = i;
                    Y = j;
                    min = i + j;
                    fa = 1;
                    break;
                }
            }
        }
    }
    if( !fa )
        return;
    Knight[X][Y] = 2;
    Knight[Y][X] = 2;
    for( int i = X + 1; i < 1001; i++ )
    {
        Knight[i][Y] = 1;
        Knight[Y][i] = 1;
    }
    for( int i = Y + 1; i < 1001; i++ )
    {
        Knight[X][i] = 1;
        Knight[i][X] = 1;
    }
    for( int i = 1; i+X < 1001 && i+Y < 1001; i++ )
    {
        Knight[X+i][Y+i] = 1;
        Knight[Y+i][X+i] = 1;
    }
    Build( X, Y );
    Build( Y, X );
}

int main()
{
    int T, N, M;
    int type;
    
    memset( Knight, false, sizeof(Knight) );
    Build( 0, 0 );

    /*for( int i = 1; i < 11; i++ )
    {
        for( int j = 1; j < 11; j++ )
            cout << Knight[i][j] << " ";
        cout << endl;
    }*/

    cin >> T;

    while( T-- )
    {
        cin >> type >> N >> M;

        if( type == 1 )
        {
            if( (M + N) % 2 == 0 && (N & 1) && (M & 1) )
                cout << "G" << endl;
            else
                cout << "B" << endl;
        }
        else if( type == 2 )
        {
            if( N == M )
                cout << "G" << endl;
            else
                cout << "B" << endl;
        }
        else if( type == 4 )
        {
            if( Knight[N][M] == 2 )
                cout << "G" << endl;
            else
                cout << "B" << endl;
        }
        else
        {
            if( N < M )
            {
                int C = N;
                N = M;
                M = C;
            }
            if( (N + M - 2) % 3 != 0 )
                cout << "D" << endl;
            else if( (N-M)>1 )
                cout << "D" << endl;
            else
            {
                int x = N + M - 2;
                if( x % 6 == 0 )
                    cout << "G" << endl;
                else
                    cout << "B" << endl;
            }
        }
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/yizhangbiao/article/details/52045786