栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

并查集-格子游戏

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

并查集-格子游戏

并查集-格子游戏

题目描述
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
#include
#include

using namespace std;

const int N = 5e4 + 10;

int group[N];	// 存储该点的父亲点的位置 

int n,m;

// 并查集 find 
int find(int x){
	if(group[x] != x) group[x] = find(group[x]);
	return group[x];
}

int main(){
	
	cin >> n >> m;
	// 初始化每个点都是一个集合 
	for(int i = 1; i <= n*n;i++){
		group[i] = i;
	}
	
	for(int i = 1; i <= m;i++){
		int x,y;
		char flag;
		cin >> x >> y >> flag;
		// 如果不-1 group 将会少最前面一行 初始化 最后一行也会缺失 
		int f = (x-1) * n + y;
		// f+n 下一行的这个点 
		if(find(f) == find(f + n) && flag == 'D'){
			cout << i << endl;
			return 0;
		//	下一列的这个点 
		}else if(find(f) == find(f + 1) && flag == 'R'){
			cout << i << endl;
			return 0;
		}
		
		//	将这个点加入到集合中 
		if(flag == 'D'){
			group[find(f+n)] = find(f); 
		}else if(flag == 'R'){
			group[find(f+1)] = find(f);
		}
	}
	cout << "draw" << endl;
	return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/605118.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号