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
原文地址:https://www.cnblogs.com/xin-hua/p/3261920.html