POJ 2386

题目描述

有一个大小为N*M的园子,雨后积起了水。八连通的积水被认为是连接在一起的。请求出园子里总共有多少水洼?(八连通指的是下图中相对W的*的部分)

***
*W*
***('W'表示积水,'.'表示没有积水)

题目分析:

要求出园子里总共有多少个水洼,就是求出园子里有多少个“连在一起”的'W',这些“堆”'W'彼此分隔,这里的连在一起指的是每个'W'在八个方向上总有一个方向能够使得和临近的'W'连接在一起,从而形成一个水洼。要算出这些水洼的数目,就需要访问所有节点直到遇到'W',然后判断这个'W'的八个方向上是否有'W',若有的话,则继续对这八个方向上的'W'进行同样的访问方法,直到访问到'.'为止则停止访问,然后返回到原始'W'的下一个八个方向上的'W',再对这个'W'执行同样的操作...;若没有则继续访问其他节点直到遇到下一个'W'或全部节点都访问过了则退出程序。这里我们为避免重复计算'W',会把访问过的'W'置为'.'。其实这整个节点访问过程就是一个深度优先搜索(DFS)过程。最后只要算出总过作了多少次DFS过程就能知道园子里有多少个水洼了。算法复杂度为O(N*M)。

 

Codes :

#include"iostream"
#include"cstdio"
#include"cstdlib"
using namespace std;
int N,M;
#define MAX 100
char field[MAX][MAX];

void dfs(int i,int j) {
    field[i][j]='.';
    for(int dx=-1; dx<=1; dx++){
        for(int dy=-1; dy<=1; dy++){
            int nx = i+dx;
            int ny = j+dy;
            if(nx>=0 && nx<N && ny>=0 && ny<M && field[nx][ny]=='W')
                dfs(nx,ny);
        }
    }
    }

int main() {
    int ans=0;
    scanf("%d%d",&N,&M);
    for(int i=0; i<N; i++) {
        for(int j=0; j<M; j++) {
            cin>>field[i][j];
        }
    }
    for(int i=0; i<N; i++) {
        for(int j=0; j<M; j++) {
            if(field[i][j]=='W') {
                dfs(i,j);
                ans++;
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}

 

posted @ 2021-01-14 11:39  青癯  阅读(100)  评论(0编辑  收藏  举报