这道题在现场做的时候莫名其妙的wa了,后来李维宇解释说因为题目数据的问题必须用%s
题解用的是DFS但是我个人并不喜欢DFS感觉太暴力了没有算法的美感。这道题我是用二维并查集做的算是写一个二维并查集的模板吧
题目传送门:http://acm.hzau.edu.cn/problem.php?id=1208
int find_r(int x,int y)
{
int sum=y*60+x;
if (Set[sum]==-1) return sum;
else
{
x=Set[sum]%60;y=Set[sum]/60;
Set[sum]=find_r(x,y);
return find_r(x,y);
}
}
void join(int x1,int y1,int x2,int y2)//将x2,y2所在的集合合并到x1,y1所在的集合中去
{
int r1=find_r(x1,y1),r2=find_r(x2,y2);
if (r1==r2) return;
else
Set[r2]=r1;
return;
}这就是二维并查集的模板说白了就是把二维降到一维而已没什么大不了的
下面给出全部代码
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
char Map[60][60];
int Set[60*60];
int find_r(int x,int y)
{
int sum=y*60+x;
if (Set[sum]==-1) return sum;
else
{
x=Set[sum]%60;y=Set[sum]/60;
Set[sum]=find_r(x,y);
return find_r(x,y);
}
}
void join(int x1,int y1,int x2,int y2)//将x2,y2所在的集合合并到x1,y1所在的集合中去
{
int r1=find_r(x1,y1),r2=find_r(x2,y2);
if (r1==r2) return;
else
Set[r2]=r1;
return;
}
int main()
{
int n,m,r1,r2;
bool bo;
while (scanf("%d %d",&n,&m)!=EOF)
{
for (int k=1;k<=n;k++)
scanf("%s",(Map[k]+1));
memset(Set,-1,sizeof(Set));
bo=0;
for (int y=1;y<=n;y++)
for (int x=1;x<=m;x++)
{
if ((y-1)>0&&Map[y][x]==Map[y-1][x])
{
r1=find_r(x,y);r2=find_r(x,y-1);
if (r1==r2) {bo=1;break;}
else join(x,y,x,y-1);
}
if ((x-1)>0&&Map[y][x]==Map[y][x-1])
{
r1=find_r(x,y);r2=find_r(x-1,y);
if (r1==r2){bo=1;break;}
else join(x,y,x-1,y);
}
}
if (bo==1) printf("Yes\n");
else printf("No\n");
}
return 0;
}大家可以看到,我这个代码里面没有任何关于题目中要求的数量>4的东西
因为完全没有必要,按这个算法求出来的yes他的个数一定是>4的
本文介绍了一种解决特定问题的二维并查集算法模板,并通过一个具体问题实例展示了其使用过程。该模板能够有效地处理二维空间中的连接性问题,避免了深度优先搜索等方法的暴力求解。
552

被折叠的 条评论
为什么被折叠?



