#include <stdio.h> #include <string.h> #include <algorithm> #include <queue> #include <iostream> using namespace std; #define maxn 1111 int e[maxn][maxn]; int n,m,k; int dir[8][2]={{1,0},{1,1},{1,-1},{0,1},{0,-1},{-1,0},{-1,1},{-1,-1}}; int ans; struct node{ int x,y; }f,ff; void bfs(int x,int y) { int i,j,xx,yy,num=1; queue<node>q; f.x=x; f.y=y; e[x][y]=3; q.push(f); while(!q.empty()) { f=q.front(); q.pop(); for(i=0;i<8;i++) { xx=dir[i][0]+f.x; yy=dir[i][1]+f.y; if(xx<0||yy<0||xx>=n||yy>=m||e[xx][yy]==3)continue; if(e[xx][yy]==2){num++;e[xx][yy]=3;continue;} e[xx][yy]=3; ff.x=xx; ff.y=yy; q.push(ff); } } ans=ans^(num%2==0?2:1); } int main() { int T,tt=0; scanf("%d",&T); while(T--) { memset(e,0,sizeof(e)); int i,j,a,b,aa,bb; scanf("%d%d%d",&n,&m,&k); for(i=0;i<k;i++) { scanf("%d%d",&a,&b); e[a][b]=1; for(j=0;j<8;j++) { aa=dir[j][0]+a; bb=dir[j][1]+b; if(aa<0||bb<0||aa>=n||bb>=m)continue; if(e[aa][bb]==0) e[aa][bb]=2; } } ans=0; for(i=0;i<n;i++) for(j=0;j<m;j++) { if(e[i][j]==0) { bfs(i,j); } } for(i=0;i<n;i++) for(j=0;j<m;j++) { if(e[i][j]==2) ans=ans^1; } if(ans!=0) printf("Case #%d: Xiemao\n",++tt); else printf("Case #%d: Fanglaoshi\n",++tt); } return 0; } /* 将区域中的部分分为,含空白区域的,和不含空白区域的。不含空白区域的必定是1个数字格,sg函数值为1 含有空白的区域,可以将空白部分看做一格,这样sg[i]就表示,有1个空格区,和i-1个数字区;后继状态为点击 空白后的必败0,和点击数字后的sg[i-1],这样就可以用sg定理求的sg函数值,并找到规律:i%2==0?2:1 之后遍历一遍,将有空白区域的全部广搜一遍,求得异或后的答案ans,最后记得还要遍历单个数字格 */ /* //求sg函数值代码如下 #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> using namespace std; #define maxn 1111 int sg[maxn];//sg[i]表示由一个空白区域加上i-1个边缘数字区的sg值 int vis[maxn]; void init() { int i,j,k; sg[0]=0; sg[1]=1; for(i=2;i<1000;i++) { memset(vis,0,sizeof(vis)); vis[sg[i-1]]=1; //点击数字区域 vis[0]=1; //点击空白区域,后继状态必败 for(j=0;;j++) if(vis[j]==0) { sg[i]=j; break; } } for(i=0;i<20;i++) cout<<sg[i]<<" "; cout<<endl; } int main() { init(); return 0; } //SG值:0 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 */