WS题目
题目大意
思路
我们一看到题目就可以知道,这是一个判断题,我们一个一个来。我们首先把题目进行转换,我们考虑把这个游戏想象成取石子,在此之前,起点设为 ( 0 , 0 ) (0,0) (0,0),终点设为 ( n − 1 , m − 1 ) (n-1,m-1) (n−1,m−1),这样好搞一点。
对于国王,我们只能 x + 1 x+1 x+1或者 y + 1 y+1 y+1或者 x + 1 , y + 1 x+1,y+1 x+1,y+1,所以就相当于两堆石子,数量为 n − 1 n-1 n−1和 m − 1 m-1 m−1,所以我们取只能第一堆取一个,或者第二堆取一个,或者两堆同时取一个,如果对手是前面两个操作,那我就跟它进行相反操作,如果是第三个,就我也两边同时取一个。所以,如果两堆都是奇数,那么后手必胜,否则,先手必胜
对于城堡,相当从任意一堆中取任意个,那就是典型的
N
i
m
Nim
Nim游戏,直接异或就好了,不用多说了
对于骑士,相当于,从任意一堆中取2个,从另外一堆中取1个,那么,就是典型的巴什博奕,就后手取先手取的反,就是的每两次操作使得两堆同时少三个石子,那么,如果n和m的和是6的倍数并且 n = m n=m n=m,那么后手必胜,否则如果后手能刚好给先手留一个,那么先手必胜,判断条件就是 m = n + 1 m=n+1 m=n+1,并且 n ≡ 1 ( m o d 3 ) n\equiv1(mod \ \ 3) n≡1(mod 3),否则,就是 D D D了
对于王后,就相当于 车 + 象 车+象 车+象,相当于从任意一堆取任意个,或者两堆同时取任意个,就是典型威佐夫博弈了,然后我们套套公式,就出来了
代码奇丑无比
#include <set>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define Int register int
#define MAXN 60005
int n,m;
void read (int &x)
{
x = 0;char c = getchar();int f = 1;
while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}
while (c >= '0' && c <= '9'){x = (x << 3) + (x << 1) + c - '0';c = getchar();}
x *= f;return ;
}
void write (int x)
{
if (x < 0){x = -x;putchar ('-');}
if (x > 9) write (x / 10);
putchar (x % 10 + '0');
}
signed main()
{
int times;
read (times);
while (times --)
{
int t;
read (t),read (n),read (m);
if (n > m) swap (n,m);
if (t == 1)
{
if (n % 2 && m % 2) puts ("G");
else puts ("B");
}
else if (t == 2)
{
if (n == m) puts("G");
else puts ("B");
}
else if (t == 3)
{
n --;m --;
if (n == m && (n + m) % 6 == 0) puts ("G");
else if (m - n == 1 && (n - 1) % 3 == 0) puts ("B");
else puts ("D");
}
else if (t == 4)
{
n --,m --;
int w = (sqrt(5) + 1) / 2 * (m - n);
if (w == n) puts ("G");
else puts ("B");
}
}
return 0;
}