C++题解——格子游戏

题目链接:一本通 TFLSOJ

思路:使用并查集给点连接,如果在连接过程中遇到已连接的点二次连接,就输出

代码:

/*这道题让我们输出最先形成闭环的步骤
我们可以用并查集,把每连过的两个点归到一个家族
每次连的时候,如果这两个点已经是一个家族的,说明这两个点连接后会形成闭环
此时输出
如果不是,就把他们连起来
思路很简单,代码很复杂 
 */ 
#include<bits/stdc++.h>
using namespace std;
struct node{
	int x,y;
};//定义一个结构体便于存储坐标 
node f[205][205];
int n,m;
node find(node k){
	if(f[k.x][k.y].x==k.x&&f[k.x][k.y].y==k.y)return f[k.x][k.y];//如果父亲是自己,返回自己 
	return f[k.x][k.y]=find(f[k.x][k.y]);//向上递归找父亲 
}//这个函数的功能是找到k结构体的父亲 
void merge(node k1,node k2){
	k1=find(k1);
	k2=find(k2);
	f[k1.x][k1.y]=k2;//k1父亲变k2 
}//这个函数的功能是合并k1 k2两个家族 
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			f[i][j].x=i;
			f[i][j].y=j;
		}
	}//初始化,每个人都是自己的父亲 
	int x,y;
	char c;
	node k1,k2;
	for(int i=1;i<=m;i++){
		cin>>x>>y>>c;
		if(c=='D'){
			k1=find(f[x][y]);
			k2=find(f[x+1][y]);//如果向下画,标记起始坐标父亲 
		}else{
			k1=find(f[x][y]);
			k2=find(f[x][y+1]);//向右画同理 
		}
		if(k1.x==k2.x&&k1.y==k2.y){
			cout<<i;       ->重要!如果连接的两个点本来就是一个家族的,那么就形成了闭环,输出 
			return 0;
		}else
			merge(k1,k2);//否则就把他们合并成一个家族 
	}
	cout<<"draw";//到最后都没有输出的话,就输出draw 
	return 0;
}
posted @ 2023-07-10 11:20  NightinGaleDekker  阅读(237)  评论(0)    收藏  举报