連通塊問題——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);
} 

運行結果:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章