当前位置: 代码迷 >> 综合 >> 【天天练3】Lake Counting (POJ No.2386)——深度优先搜索
  详细解决方案

【天天练3】Lake Counting (POJ No.2386)——深度优先搜索

热度:20   发布时间:2024-02-08 20:34:25.0

题目内容:

                               Lake Couting (POJ No.2386)

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

样例

输入:

N = 10,M = 20
园子如下图 ( ‘W’ 表示积水, ‘.’ 表示没有积水 )
W . . . . . . . . W W .
.W W W . . . . . W W W
. . . . W W . . . W W .
. . . . . . . . . W W .
. . . . . . . . . W . .
. . W . . . . . . W . .
. W . W . . . . . W W .
W . W . W . . . . . W .
. W . W . . . . . . W .
. . W . . . . . . . W .

输出:

3

解题思路:

按照顺序,从第一个W开始,不停的把邻接部分的 ‘W’ 用 ’ . ’ 代替,一次DFS之后包含第一个W的连通域中的’W’全部被 ’ . ’ 替换。直到图中不存在 ‘W’ 为止,所经历的DFS的次数,就是连通域的个数。
具体细节:
我们可以用两个for来进行八个方向的转移:

for(int dx = -1; dx <= 1; dx++)for(int dy = -1; dy <= 1; dy++)

用两个for来寻找’W’:

for(int i = 0; i < M; i++)for(int j = 0; j < N; j++)if(field[i][j] == 'W')

代码实现:

int N,M;
char field [100][101];
void dfs(int x,int y){field[x][y] = '.'; //将现在所在的位置替换为 '.'for(int dx = -1; dx <= 1; dx++){for(int dy = -1; dy <= 1; dy++){int nx = x + dx;int ny = y + dy;if(nx >= 0 && nx < N && ny >= 0 && ny < M && field[nx][ny] == 'W')dfs(nx,ny);}}return ;
} 
void solve(){int res = 0;for(int i = 0; i < N; i++){for(int j = 0; j < M; j++){if(field[i][j] == 'W')dfs(i,j);res++;}}cout << res << endl;
}