给定一个n*m的矩阵,有四种棋子(国际象棋的王,王后,骑士,车)。起点在(1,1)先走到(n,m)获胜。
分析:车是nim博弈。王后是威佐夫博弈。王和骑士写两个1000*1000的预处理即可。
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\n"); 64 else printf("G\n"); 65 } else if (x==2) { 66 xo=(n-1)^(m-1); //因为第一个位置是(1,1),不是(0,0); 67 if (xo) printf("B\n"); 68 else printf("G\n"); 69 } else if (x==3) { 70 if (g[n][m]==-1) printf("D\n"); 71 else if (g[n][m]==1) printf("B\n"); 72 else printf("G\n"); 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\n"); 78 else if (n==(int)((x+1)*(1+sqrt(5))/2)&&n+x+1==m) printf("G\n"); 79 else printf("B\n"); 80 } 81 } 82 return 0; 83 }
时间: 2024-10-29 10:46:14