油田(Oil Deposits, UVa 572)

题意:

   多组案例,每组案例输入一个m行n列的字符矩阵,统计字符‘@’组成多少个连通块。如果两个字符‘@’所在的格子相邻(横、竖或对角线),则说明它们属于同一连通块。

案例:

   Sample Input

   1 1

   *

   3 5

   *@*@*

   **@**

   *@*@*

   1 8

   @@****@*

   5 5

   ****@

   *@@*@

   *@**@

   @@@*@

   @@**@

   0 0

   Sample Output

   0

   1

   2

   2

用DFS求连通块,从每个‘@’格子出发,递归其周围的‘@’格子,每访问一个格子时给其写上连通编号,避免同一格子访问多次。

//优先搜索@的周围8个
#include<iostream>
#include<cstring> 
const int maxn=105;
char pic[maxn][maxn];
int m,n;
int idx[maxn][maxn]; //标记,避免多次访问 
void dfs(int r,int c,int id)
{
	if(r<0||r>=m||c<0||c>=n)   //出界了 
		return;
	if(idx[r][c]>0||pic[r][c]!='@') return;
	idx[r][c]=id; //连通分量编号 
	for(int dr=-1;dr<=1;dr++) //周围那8块 
	{
		for(int dc=-1;dc<=1;dc++)
		{
			if(dr!=0||dc!=0)
			dfs(r+dr,c+dc,id);
		}
	} 
} 
int main()
{
	while(cin>>m>>n&&m&&n)
	{
		for(int i=0;i<m;i++)
		{
			cin>>pic[i];
		}
		memset(idx,0,sizeof(idx));
		int cnt=0;
		for(int i=0;i<m;i++)
		{
			for(int j=0;j<n;j++)
			{
				if(idx[i][j]==0&&pic[i][j]=='@')
					dfs(i,j,++cnt);     //进入判断第一个连通块 
			}
		}
		cout<<cnt<<endl;
	}
	return 0;
}
 posted on 2020-04-24 23:09  My_serendipity  阅读(153)  评论(0编辑  收藏  举报