动规(16)-并查集基础题——格子游戏

【问题描述】

AliceBob玩了一个古老的游戏:首先画一个n * n的点阵(下图n = 3   接着,他们两个轮流在相邻的点之间画上红边和蓝边:

直到围成一个封闭的圈(面积不必为1)为止,“封圈”的那个人就是赢家。因为棋盘实在是太大了(n<= 200),他们的游戏实在是太长了!他们甚至在游戏中都不知道谁赢得了游戏。于是请你写一个程序,帮助他们计算他们是否结束了游戏?

【输入格式】

输入数据第一行为两个整数nmm表示一共画了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 <cstdio>
#include <iostream>
using namespace std;
int fa[40001], n, m, x, y, r1, r2, xx, yy;
char ch;
int find(int u)
{
	return fa[u] == u ? u : fa[u] = find(fa[u]);
}
int read()
{
	int x = 0;
	char ch = getchar();
	while (!isdigit(ch))
		ch = getchar();
	while (isdigit(ch))
		x = x * 10 + ch - 48, ch = getchar();
	return x;
}
int main()
{
	cin >> n >> m;
	for (int i = 1; i <= n * n; i++)
		fa[i] = i;
	for (int i = 1; i <= m; i++)
	{
		x = read();
		y = read();
		cin >> ch;
		xx = n * (x - 1) + y;
		if (ch == 'D')
			yy = xx + n;
		else
			yy = xx + 1;
		r1 = find(xx);
		r2 = find(yy);
		if (r1 != r2)
			fa[r1] = r2;
		else
		{
			cout << i;
			return 0;
		}
	}
	cout << "draw" << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/hdq1745/article/details/126041454
今日推荐