给定一个n*m的矩阵,有四种棋子(国际象棋的王,王后,骑士,车)。起点在(1,1)先走到(n,m)获胜。

分析:车是nim博弈。王后是威佐夫博弈。王和骑士写两个1000*1000的预处理即可。

hdu5754Life Winner Bo 题目连接

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=;
int f[N][N],g[N][N];
void deal1()
{
int i,j;
f[][]=;
for(i=;i<=;i++)
for(j=;j<=;j++)
{ if(i==&&j==)continue;
else
{
f[i][j]=;
if(i>&&f[i-][j]==)f[i][j]=;
if(j>&&f[i][j-]==)f[i][j]=;
if(i>&&j>&&f[i-][j-]==)f[i][j]=;
}
}
} void deal2()
{
int i,j,d,e;
g[][]=;g[][]=-;
for(i=;i<=;i++)g[][i]=g[i][]=-;
for(i=;i<=;i++)
for(j=;j<=;j++)
{
if(j==&&i==)continue;
else
{
d=;e=;
if(i>)d++;if(j>)d++;
if(i>&&g[i-][j-]==)e++;
if(j>&&g[i-][j-]==)e++;
if(d==e)g[i][j]=;//所有的后继都为必胜,则它为必败态
else
{
if((j>&&g[i-][j-]==)||(i>&&g[i-][j-]==))
g[i][j]=;//后继有一个必败态,则它为必胜态
else
g[i][j]=-;//不是必胜态或必败态那么这个位置不满足条件
}
} }
}
int main()
{ int i,x,n,m,t,xo;
scanf("%d", &t);
deal1();deal2();
while (t--) {
scanf("%d%d%d", &x, &n, &m);
if (x==) {
if (f[n][m]==) printf("B\n");
else printf("G\n");
} else if (x==) {
xo=(n-)^(m-); //因为第一个位置是(1,1),不是(0,0);
if (xo) printf("B\n");
else printf("G\n");
} else if (x==) {
if (g[n][m]==-) printf("D\n");
else if (g[n][m]==) printf("B\n");
else printf("G\n");
} else {
n--;m--; //同理
if (n>m) swap(n,m);
x=(int)(n*(sqrt()-)/);
if (n==(int)(x*(+sqrt())/)&&n+x==m) printf("G\n");
else if (n==(int)((x+)*(+sqrt())/)&&n+x+==m) printf("G\n");
else printf("B\n");
}
}
return ;
}
04-14 12:31