给定一个n*m的矩阵,有四种棋子(国际象棋的王,王后,骑士,车)。起点在(1,1)先走到(n,m)获胜。
分析:车是nim博弈。王后是威佐夫博弈。王和骑士写两个1000*1000的预处理即可。
hdu5754Life Winner Bo 题目连接
1 #include<iostream>
2 #include<cstdio>
3 #include<cmath>
4 #include<algorithm>
5 using namespace std;
6 const int N=1010;
7 int f[N][N],g[N][N];
8 void deal1()
9 {
10 int i,j;
11 f[1][1]=1;
12 for(i=1;i<=1000;i++)
13 for(j=1;j<=1000;j++)
14 {
15
16 if(i==1&&j==1)continue;
17 else
18 {
19 f[i][j]=1;
20 if(i>1&&f[i-1][j]==1)f[i][j]=0;
21 if(j>1&&f[i][j-1]==1)f[i][j]=0;
22 if(i>1&&j>1&&f[i-1][j-1]==1)f[i][j]=0;
23 }
24 }
25 }
26
27 void deal2()
28 {
29 int i,j,d,e;
30 g[1][1]=0;g[2][2]=-1;
31 for(i=2;i<=1000;i++)g[1][i]=g[i][1]=-1;
32 for(i=2;i<=1000;i++)
33 for(j=2;j<=1000;j++)
34 {
35 if(j==2&&i==2)continue;
36 else
37 {
38 d=0;e=0;
39 if(i>2)d++;if(j>2)d++;
40 if(i>2&&g[i-2][j-1]==1)e++;
41 if(j>2&&g[i-1][j-2]==1)e++;
42 if(d==e)g[i][j]=0;//所有的后继都为必胜,则它为必败态
43 else
44 {
45 if((j>2&&g[i-1][j-2]==0)||(i>2&&g[i-2][j-1]==0))
46 g[i][j]=1;//后继有一个必败态,则它为必胜态
47 else
48 g[i][j]=-1;//不是必胜态或必败态那么这个位置不满足条件
49 }
50 }
51
52 }
53 }
54 int main()
55 {
56
57 int i,x,n,m,t,xo;
58 scanf("%d", &t);
59 deal1();deal2();
60 while (t--) {
61 scanf("%d%d%d", &x, &n, &m);
62 if (x==1) {
63 if (f[n][m]==0) printf("B
");
64 else printf("G
");
65 } else if (x==2) {
66 xo=(n-1)^(m-1); //因为第一个位置是(1,1),不是(0,0);
67 if (xo) printf("B
");
68 else printf("G
");
69 } else if (x==3) {
70 if (g[n][m]==-1) printf("D
");
71 else if (g[n][m]==1) printf("B
");
72 else printf("G
");
73 } else {
74 n--;m--; //同理
75 if (n>m) swap(n,m);
76 x=(int)(n*(sqrt(5)-1)/2);
77 if (n==(int)(x*(1+sqrt(5))/2)&&n+x==m) printf("G
");
78 else if (n==(int)((x+1)*(1+sqrt(5))/2)&&n+x+1==m) printf("G
");
79 else printf("B
");
80 }
81 }
82 return 0;
83 }