hdu 4678 Mine 博弈论

这是一题简单的博弈论!!

所有的空白+边界的数字(个数为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 }
View Code

 

 

 

你可能感兴趣的:(HDU)