连通块问题——DFS——C++详解

问题描述:

输入一个m行n列的字符矩阵,统计字符“@”组成多少个八连块。
如果两个字符“@”所在的格子相邻(横、竖或者对角线方向),就说他们属于同一个八连块。
例如,下图中有两个八连块 

****@
*@@*@
@***@
@@***
@@@** 

代码一如下:

#include<bits/stdc++.h>
#define maxn 100+5 
using namespace std;
char ch[maxn][maxn];
int m,n,idx[maxn][maxn];
void dfs(int r,int c,int id)
{
	int dr,dc;
	if(r<0||r>=m||r<0||r>=n)			//出界 
		return;
	if(idx[r][c]>0||ch[r][c]!='@')		        //已被标记或者符号不为@ 
		return;
	idx[r][c]=id;
	for(dr=-1;dr<=1;++dr)				//向四周搜索 
	{
		for(dc=-1;dc<=1;++dc)
		{
			if(dc!=0||dr!=0)		//如果dc==0&&dr==0,位置不改变 
			{
				dfs(r+dr,c+dc,id);	//id不变 
			}
		}
	}
}
int main()
{
	int i,j,cnt=0;
	scanf("%d%d",&m,&n);
	memset(idx,0,sizeof(idx));
	for(i=0;i<m;++i)
		scanf("%s",ch[i]);
	for(i=0;i<m;++i)
	{
		for(j=0;j<n;++j)
		{
			if(idx[i][j]==0&&ch[i][j]=='@')	//符号位置未被标记且符号为@ 
				dfs(i,j,++cnt);		//给不同的连块给予不同的编号,从1开始编号 
		}
	}
	printf("%d\n",cnt);
	return 0;
}

代码二如下:

#include<cstdio>
using namespace std;
char map[105][105];
int visited[105][105]; 
int dir[8][2]={{-1,-1},{0,-1},{1,-1},{1,0},{1,1},{0,1},{-1,1},{-1,0}};
int m,n;
void dfs(int x,int y){
	if(x<0||x>=m||y<0||y>=n||visited[x][y]||map[x][y]=='*')
		return;
	visited[x][y]=1;
	for(int i=0;i<8;++i){
		int tx=x+dir[i][0];
		int ty=y+dir[i][1];
		dfs(tx,ty);
	}
}
int main(){
	int cnt=0;
	scanf("%d%d",&m,&n);
	for(int i=0;i<m;++i)	
		scanf("%s",map[i]);
	for(int i=0;i<m;++i){
		for(int j=0;j<n;++j){
			if(!visited[i][j]&&map[i][j]=='@'){
				dfs(i,j);
				++cnt;
			}
		}
	}
	printf("%d\n",cnt);
} 

运行结果:

发布了23 篇原创文章 · 获赞 10 · 访问量 1759

猜你喜欢

转载自blog.csdn.net/weixin_45953673/article/details/104626161