H — Color ring(dfs)

1.PNG

 2.PNG

 3.PNG

   Sample Input 1

    3 4
    AAAA
    ABCA
    AAAA

Sample Output 1

  Yes

题目中给的n、m的范围是0~50,所以可以直接暴力枚举,把所有点都遍历一遍,用 flag 标记是否有环出现,一旦 flag==1,跳出所有循环,难点是如何找环,其实只需要那开始dfs的点,和遍历到最后的点做一下判断,看它们是否相邻,且ans要大于等于4,即 if(ans>=4&&( (abs(x1-ex)==0 && abs(y1-ey)==1 ) || ( abs(x1-ex)==1 && abs(y1-ey)==0 ) ) )

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cmath>
using namespace std;
const int M=60;
char str[M][M];
int vis[M][M];
int n,m,ans,flag,ex,ey,x2,y2;
int p[2][4]={{1,-1,0,0},{0,0,1,-1}};
 
bool check(int x,int y){////判断是否是合法的点 
	if(x>=0&&x<n&&y>=0&&y<m&&!vis[x][y])
		return true;
	return false;
}

void dfs(int x1,int y1){
	ans++;//记录步数
	vis[x1][y1]=1;
	for(int i=0;i<4;i++){
		x2=x1+p[0][i];
		y2=y1+p[1][i];
		if(check(x2,y2)){
			if(str[x1][y1]==str[x2][y2]){////如果满足条件就继续搜索
				dfs(x2,y2);
			}
		}
	}
	//判断搜到尽头的那个点是否和起点相邻,步数是否大于4
	if(ans>=4&&( (abs(x1-ex)==0 && abs(y1-ey)==1 )||
	( abs(x1-ex)==1 && abs(y1-ey)==0 ))){//注意括号的使用,这里wa了好几次 
		flag=1;
		return ;
	}
	else ans=0;
}
int main()
{
	while(scanf("%d%d",&n,&m)!=EOF&&(n||m)){
		memset(str,0,sizeof(str));
		for(int i=0;i<n;i++){
			scanf("%s",str[i]);
		}
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++){
				ans=0;
				flag=0; 
				memset(vis,0,sizeof(vis));//每搜一个点,判断完后都要清除标记,以便后面的点的搜索
				if(!vis[i][j]){
					ex=i;//开始坐标 
					ey=j;//开始坐标
					dfs(i,j);
					if(flag) break;//跳出i 
				}		
				if(flag) break;//跳出j 
			}
		if(flag) puts("Yes");
		else puts("No");
	}
	return 0;
 } 

猜你喜欢

转载自blog.csdn.net/qq_41555192/article/details/82152288