格子游戏x(并查集)
格子游戏
【问题描述】
Alice和Bob玩了一个古老的游戏:首先画一个n * n的点阵(下图n = 3) 接着,他们两个轮流在相邻的点之间画上红边和蓝边:
直到围成一个封闭的圈(面积不必为1)为止,“封圈”的那个人就是赢家。因为棋盘实在是太大了(n <= 200),他们的游戏实在是太长了!他们甚至在游戏中都不知道谁赢得了游戏。于是请你写一个程序,帮助他们计算他们是否结束了游戏?
【输入格式】
输入数据第一行为两个整数n和m。m表示一共画了m条线。以后m行,每行首先有两个数字(x, y),代表了画线的起点坐标,接着用空格隔开一个字符,假如字符是"D ",则是向下连一条边,如果是"R "就是向右连一条边。输入数据不会有重复的边且保证正确。
【输出格式】
输出一行:在第几步的时候结束。假如m步之后也没有结束,则输出一行“draw”。
【输入样例】
3 5
1 1 D
1 1 R
1 2 D
2 1 R
2 2 D
【输出样例】
4
1 #include<iostream> 2 #include<cstdio> 3 #define Maxn 2002 4 5 using namespace std; 6 7 int n,m; 8 9 struct zuobiao{ 10 int x,y; 11 }zb[Maxn][Maxn],f1,f2; 12 13 zuobiao gz(zuobiao q) 14 { 15 if(zb[q.x][q.y].x==q.x&&zb[q.x][q.y].y==q.y) return q; 16 zb[q.x][q.y]=gz(zb[q.x][q.y]); 17 return zb[q.x][q.y]; 18 } 19 int main() 20 { 21 int x,y; 22 char zifu; 23 scanf("%d%d",&n,&m); 24 for(int i=1;i<=n;i++)//初始化操作 25 { 26 for(int j=1;j<=n;j++) 27 { 28 zb[i][j].x=i; 29 zb[i][j].y=j; 30 } 31 } 32 for(int i=1;i<=m;i++) 33 { 34 cin>>x>>y>>zifu; 35 if(zifu=='D')//down 36 { 37 f1=gz(zb[x][y]); 38 f2=gz(zb[x+1][y]); 39 } 40 if(zifu=='R')//right 41 { 42 f1=gz(zb[x][y]); 43 f2=gz(zb[x][y+1]); 44 } 45 if(f1.x==f2.x&&f1.y==f2.y) 46 { 47 cout<<i<<endl; 48 return 0; 49 } 50 else zb[f1.x][f1.y]=f2; 51 } 52 cout<<"draw"<<endl; 53 return 0; 54 }