油田(Oil Deposits,UVa 572)

题目链接: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 }
原文地址:https://www.cnblogs.com/huaszjh/p/4686092.html