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

【刷题】数据结构——并查集:格子游戏

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

【刷题】数据结构——并查集:格子游戏


题目是寻找第一次成环的时刻。

可以用并查集来维护各个点,如果两点间有边,则两点属于一个集合。只要看加上这条边之前两点是否在一个集合,即可判断成环的时刻。

因为n只有200,假设坐标编号是0~199,因此用 200 ∗ x + y 200*x + y 200∗x+y就可以不重复的表示所有坐标。
换而言之,假设坐标编号是0~n-1,用 n ∗ x + y n*x+y n∗x+y

当 ( x , y ) (x, y) (x,y)向下连线时, ( x , y ) (x, y) (x,y)与 ( x + 1 , y ) (x+1, y) (x+1,y)进行合并
当 ( x , y ) (x, y) (x,y)向右连线时, ( x , y ) (x, y) (x,y)与 ( x , y + 1 ) (x, y+1) (x,y+1)进行合并
合并前需判断两点是否已经在一个集合,如果在则直接输出当前步数。

#include 
using namespace std;

const int N = 40005;

int n, m;
int p[N], idx;

int find(int x) {
	if (p[x] != x) p[x] = find(p[x]);
	return p[x];
}

int main() {
	scanf("%d%d", &n, &m);
	int a, b, x, y;
	char op[2];

	for (int i = 0 ; i <= n * (n - 1) + n - 1; i ++ ) {
		p[i] = i;
	}
	
	for (int i = 1; i <= m; i ++ ) {
		scanf("%d%d%s", &x, &y, op);
		x -- ; y -- ; // 坐标从1~n换成0~n-1 
		a = n * x + y;
		if (op[0] == 'D') b = n * (x + 1) + y;
		else b = n * x + y + 1;
		if (find(a) == find(b)) {
			printf("%dn", i);
			return 0;
		}
		p[find(a)] = find(b);
	}
	printf("drawn");
	return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/718564.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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