题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5754
思路:
具体走法在代码中标注。
type==1:找规律可以找到,若横、纵坐标都是奇数那么先手必败,(看别人的题解说是巴什博奕,但不知道为啥qwq)
type==2:相当于基本的nim博弈,只能横、竖走,横走n-1,竖走m-1,把他们想象成取石子
type==3:走日分为两种走法,第一种向右,第二种向下,设向右走x个日,向下走y个,那么2x+y=m-1,x+2y=n-1
解得:x=(2m-1-n)/3,y=(2n-m-1)/3,x+y=(n+m-2)/3,若x+y不是整数,那么输出D,没有赢家。
设t=abs(x-y),若t==1那么先手必定会赢,若t==0那么后手一定会赢,若t>=2,必定有人制造平局。
type==4:威佐夫博弈
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cmath>
#include<set>
#include<string>
#include<cstring>
#define ll long long
using namespace std;
const int N=100005;
int dep[N],a[N];
int main(){
int t,k,n,m;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&k,&n,&m);
if(k==1){//王走横、直、斜,每次一步
if(n%2==0||m%2==0){
printf("B\n");
}
else printf("G\n");
}
if(k==2){//横竖均可走不受限制
int ans=0;
ans^=(n-1);
ans^=(m-1);
if(ans)printf("B\n");
else printf("G\n");
}
if(k==3){//马走日
if((n+m-2)%3)printf("D\n");
else {
int r=(2*m-n-1)/3,d=(2*n-m-1)/3;
if(abs(r-d)>=2){
printf("D\n");
}
else if(abs(r-d)==1)printf("B\n");
else printf("G\n");
}
}
if(k==4){//横竖斜均可走不受限制
int x=n-1,y=m-1;
if(x>y)swap(x,y);
int tmp=floor((y-x)*(1+sqrt(5.0))/2.0);
if(tmp==x)printf("G\n");
else printf("B\n");
}
}
}