POJ 2386 Lake Counting(深度优先搜索)

来源:互联网 发布:智多星软件 编辑:程序博客网 时间:2024/06/07 05:58

原题地址

http://poj.org/problem?id=2386

题意:有一个大小为N*M的园子,雨后有的格子积了水。八连通((i, j)为中心的九宫格的其余格子)的积水被认为是连续的一片水洼,求出园子里总共有多少水洼。

解题思路

本题是典型的枚举搜索题,一开始没有想到比较顺畅直接的解法,后来看了书(《挑战程序设计竞赛》P33)才发现,搜索的同时可以改变搜索对象来帮助解题。

从任意的W开始,不停地把邻接的部分用.来代替。那么1次大DFS后与初始的这个W连接的所有W就都被替换成了.,再找下一个W,继续DFS直到图中不再存在W为止,最终答案即大的DFS的次数。
8个方向对应8个状态转移,每个格子作为DFS的参数至多被调用一次。所以复杂度为O(8*N*M) = O(N*M)

AC代码

#include <iostream>using namespace std;const int maxn = 105;char field[maxn][maxn];int n, m;void print_field(){    cout << endl;    for (int i = 0; i<n; ++i)    {        for (int j = 0; j<m; ++j)            cout << field[i][j];        cout << endl;    }}void dfs(int r, int c){    field[r][c] = '.'; //该方格置为空    //对W方格的八个方向深度搜索    int dx, dy, nx, ny;    for (dx = -1; dx <= 1; ++dx)    {        nx = r+dx;        for (dy = -1; dy <= 1; ++dy)        {            ny = c+dy;            if(0 <= nx && nx < n && 0 <= ny && ny < m && field[nx][ny] == 'W')                dfs(nx, ny); //对附近的W方格深搜        }    }    return;}void solve(){    int ans = 0;    for (int i = 0; i<n; ++i)        for (int j = 0; j<m; ++j)        {            if (field[i][j] == 'W')            {                dfs(i, j);                ans++;                //print_field();观察每次的变化            }        }    cout << ans << endl;}int main(){    ios::sync_with_stdio(false);    cin >> n >> m;    for (int i = 0; i < n; ++i)        cin >> field[i];    //print_field();    solve();    return 0;}

算法复杂度:O(n*m)
耗时:0ms

0 0
原创粉丝点击