这是一题简单的博弈论!!
所有的空白+边界的数字(个数为n)为一堆,容易推出其SG函数值为n%2+1;
其他所有的数字(个数为m)的SG值为m%2。
再就是用dfs将空白部分搜一下即可!(注意细节)
代码如下:
1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 #include<iomanip> 5 #include<cmath> 6 #include<cstring> 7 #include<vector> 8 #define MAX 1005 9 #pragma comment(linker,"/STACK:1024000000,1024000000") 10 using namespace std; 11 int vis[MAX][MAX],m,n,k,tot,cnt,ans,num; 12 int d[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}}; 13 int cal(int i,int j) 14 { 15 int ans=0; 16 if(i-1>=0){ 17 ans+=(vis[i-1][j]==-1); 18 if(j-1>=0) ans+=(vis[i-1][j-1]==-1); 19 if(j+1<m) ans+=(vis[i-1][j+1]==-1); 20 } 21 if(j-1>=0){ 22 ans+=(vis[i][j-1]==-1); 23 if(i+1<n) ans+=(vis[i+1][j-1]==-1); 24 } 25 if(j+1<m){ 26 ans+=(vis[i][j+1]==-1); 27 if(i+1<n) ans+=(vis[i+1][j+1]==-1); 28 } 29 if(i+1<n) ans+=(vis[i+1][j]==-1); 30 return ans; 31 } 32 void dfs(int a,int b) 33 { 34 int t,u,v; 35 if(vis[a][b]==-1) return; 36 if(vis[a][b]>=0){ 37 vis[a][b]=-3; 38 num++;tot++; 39 return; 40 } 41 if(vis[a][b]==-2){ 42 t=cal(a,b); 43 tot++; 44 vis[a][b]=-3; 45 if(t==0){ 46 for(int i=0;i<8;i++){ 47 u=a+d[i][0]; 48 v=b+d[i][1]; 49 if(u>=0&&u<n&&v>=0&&v<m) 50 dfs(u,v); 51 } 52 } 53 else{ 54 num++; 55 return ; 56 } 57 } 58 else return ; 59 } 60 void solve() 61 { 62 int i,j,k,u,v; 63 tot=0;cnt=0;ans=0; 64 for(i=0;i<n;i++){ 65 for(j=0;j<m;j++){ 66 if(vis[i][j]==-2){ 67 int t=cal(i,j); 68 if(t>0) vis[i][j]=t; 69 else{ 70 tot++;cnt++; 71 num=0; 72 vis[i][j]=-3; 73 for(k=0;k<8;k++){ 74 u=i+d[k][0]; 75 v=j+d[k][1]; 76 if(u>=0&&u<n&&v>=0&&v<m) 77 dfs(u,v); 78 } 79 ans^=(num%2+1); 80 } 81 } 82 } 83 } 84 return ; 85 } 86 int main(){ 87 int t,i,j,u,v,w=0; 88 scanf("%d",&t); 89 while(t--){ 90 scanf("%d%d%d",&n,&m,&k); 91 for(i=0;i<n;i++) 92 for(j=0;j<m;j++) 93 vis[i][j]=-2; 94 for(i=0;i<k;i++){ 95 scanf("%d%d",&u,&v); 96 vis[u][v]=-1; 97 } 98 solve(); 99 int ans1=(n*m-k-tot)%2; 100 printf("Case #%d: ",++w); 101 if(ans1^ans) puts("Xiemao"); 102 else puts("Fanglaoshi"); 103 } 104 return 0; 105 }