题目描述:
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 x′≥x and y′≥y.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.
T≤1000,2≤N,M≤1000,1≤type≤4
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
题目分析:
2016hdu多校第三场的第三题。
讲的是两个人在一个n*m的棋盘上挪动一个棋子,这个棋子有王车马后四种(走法和国际象棋走法一致),从(1,1)点走到(n,m)点,只能往下方或者右方走,问,两人以最佳策略,谁能获胜,或者平局(即两人都走不到(n,m)点)。
相当于两堆石子,n-1个和m-1个,以不同方法取,最先取完的获胜。
四种情况分别分析:
1.王的情况:从其中一堆取一个,或者两堆各取一个。可以分析,这两堆石子同为偶数时,后手胜,否则先手胜。
2.车的情况:从其中一堆取任意个。这个最简单,两堆一样多,就后手胜,否则先手胜。(相当于只有两堆的尼姆博弈)
3.马的情况:从其中一堆取1或2个,同时从另一堆中取2或1个。这个需要推导,若两堆相同并且能被3整除,后手胜;两堆中多的比少的多一个,并且多的那一堆对3取余为2(少的那一堆对3取余为1),先手胜;否则,平局。
4.后的情况:从其中一堆取任意个,或者从两堆都取任意相同个。完完全全的威佐夫博奕。
代码如下:
#include <iostream>
#include <cstdio>
#include <math.h>
using namespace std;
int t,m,n;
int T;
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&t,&n,&m);
if (n>m) swap(n,m);
if (t==1)
{
n--;m--;
if ((n%2==0) && (m%2==0)) printf("G\n");
else printf("B\n");
}
else if (t==2)
{
n--;m--;
if (n==m) printf("G\n");
else printf("B\n");
}
else if (t==3)
{
n--;
m--;
if ((n%3==0) && (n==m)) printf("G\n");
else if ((m%3==2) && ((m-n)==1)) printf("B\n");
else printf("D\n");
}
else if (t==4)
{
n--;
m--;
int k=m-n;
m=(int)(k*(1+sqrt(5))/2.0);
if(n==m)
printf("G\n");
else
printf("B\n");
}
}
return 0;
}