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;
}

浙公网安备 33010602011771号