题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=84562#problem/L
题意:
多组案例,每组案例输入一个m行n列的字符矩阵,统计字符‘@’组成多少个连通块。如果两个字符‘@’所在的格子相邻(横、竖或对角线),则说明它们属于同一连通块。
案例:
Sample Input
1 1
*
3 5
*@*@*
**@**
*@*@*
1 8
@@****@*
5 5
****@
*@@*@
*@**@
@@@*@
@@**@
0 0
Sample Output
0
1
2
2
分析:
用DFS求连通块,从每个‘@’格子出发,递归其周围的‘@’格子,每访问一个格子时给其写上连通编号,避免同一格子访问多次。
源代码:
1 #include<cstdio> 2 #include<cstring> 3 const int maxn=105; 4 char a[maxn][maxn]; 5 int m,n,b[maxn][maxn]; 6 void dfs(int x,int y,int ans) 7 { 8 if(x<0||x>=m||y<0||y>=n) return;//出界格子 9 if(b[x][y]>0||a[x][y]=='*') return;//非‘@’或已经访问 10 b[x][y]=ans;//连通分量编号 11 for(int k=-1;k<=1;k++)//访问四周是否存在连通的格子 12 for(int t=-1;t<=1;t++) 13 if(k!=0||t!=0)//自身格子不需重复判断 14 dfs(x+k,y+t,ans); 15 } 16 int main() 17 { 18 int i,j; 19 while(scanf("%d%d",&m,&n)&&m&&n) 20 { 21 int count=0;//连通块 22 memset(b,0,sizeof(b));//清零 23 for(i=0;i<m;i++) 24 scanf("%s",a[i]);//输入数据 25 for(i=0;i<m;i++) 26 for(j=0;j<n;j++) 27 if(b[i][j]==0&&a[i][j]=='@')//对未访问且为‘@’的格子进行访问 28 dfs(i,j,++count); 29 printf("%d ",count); 30 } 31 return 0; 32 }