A27701. 格子游戏
题目描述
格子游戏
题目描述
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参考答案
#include<bits/stdc++.h>
using namespace std;
#define N 40005
int fa[N], n, m;
int getNum(int x, int y)//用1个数字代表二维的坐标点
{
return (x-1)*n + y;
}
void init(int n)
{
for(int i = 1; i <= n; ++i)
fa[i] = i;
}
int find(int x)
{
if(x == fa[x])
return x;
else
return fa[x] = find(fa[x]);
}
void merge(int x, int y)
{
fa[find(x)] = find(y);
}
int main()
{
int x, y, i, f, t;
char c;
cin >> n >> m;
init(n*n);
for(i = 1; i <= m; ++i)//i:第几步
{
cin >> x >> y >> c;
f = getNum(x, y);
if(c == 'D')
t = getNum(x+1, y);
else//c == 'R'
t = getNum(x, y+1);
if(find(f) == find(t))
break;
else
merge(f, t);
}
if(i <= m)
cout << i;
else
cout << "draw";
return 0;
}答案解析
方法2:直接使用坐标作为并查集中的元素
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> Pair;
map<Pair, Pair> fa;
Pair find(Pair x)
{
if(x == fa[x])
return x;
else
return fa[x] = find(fa[x]);
}
void merge(Pair x, Pair y)
{
fa[find(x)] = find(y);
}
int main()
{
Pair p, q;
int n, m, x, y;
char c;
cin >> n >> m;
for(int i = 1; i <= m; ++i)
{
cin >> x >> y >> c;
p = Pair(x, y);
if(c == 'D')
q = Pair(x+1, y);
else//c == 'R'
q = Pair(x, y+1);
if(fa.count(p) == 0)//如果不存在该点,则初始化
fa[p] = p;
if(fa.count(q) == 0)
fa[q] = q;
if(find(p) == find(q))//p, q已连通,p,q再连边,则存在环
{
cout << i;//输出步数
return 0;
}
merge(p, q);//合并两点
}
cout << "draw";
return 0;
}