https://vjudge.net/problem/UVA-572(uva572 点击打开链接)
算法:种子填充法(求多维数组连通块的过程也称为种子填充)
分析:从每个’@’格子出发,递归遍历他周围的’@’格子。每次访问一个格子时就给它写上一个“连通分量编号”(即下面代码中的idx数组),这样就可以在访问之前检查他是否已经有了编号,从而避免同一个格子访问多次。dfs用递归实现。
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
const int maxn = 100 + 10;
char ch[maxn][maxn];
int idx[maxn][maxn];
int n,m;
void dfs(int a,int b,int id)
{
//出界的格子
if(a < 1 || a > m || b < 1 || b > n)return;
//不是'@'或者已经访问过的格子
if(idx[a][b] || ch[a][b] != '@')return;
idx[a][b] = id;//连通分量的编号
for(int i = -1;i <= 1;i++)//横,竖,对角线的方向
{
for(int j = -1;j <= 1;j++)
{
if(i != 0 || j != 0)
{
dfs(a+i,b+j,id);//能走到这一步的都是同一个连通分量里的
}
}
}
}
int main()
{
while(scanf("%d%d",&m,&n) && m)
{
int cnt = 0;
for(int i = 1;i <= m;i++)
{
scanf("%s",ch[i]);
}
memset(idx,0,sizeof(idx));
for(int i = 1;i <= m;i++)
{
for(int j = 1;j <= n;j++)
{
if(ch[i][j] == '@' && !idx[i][j])
{
dfs(i,j,++cnt);
}
}
}
printf("%d\n",cnt);
}
}