题目
有一个大小为
的园子,雨后积起了水。八连通的积水被认为是连接在一起的。请求出园子里总共有多少水洼?八连通指的是下图中相对
的
的部分,'W'
表示积水,''
表示没有积水;
输入
W********WW*
*WWW*****WWW
****WW***WW*
*********WW*
*********W**
**W******W**
*W*W*****WW*
W*W*W*****W*
*W*W******W*
**W*******W*
输出
3
分析
采用深度优先搜索的思路,从任意的W
位置开始,不停的把邻接的W
替换成*
,1次dfs()
之后与初始的这个W
相连的所有W
就都被替换成了*
,循环遍历数组,直至没有W
,那么总共进行的dfs()
的次数就是连通的积水数。
8个方向共对应了8种状态转移,每个格子作为dfs()
的参数至多被调用一次(即若当前格子满足dfs()
条件,则dfs()
中又会有8次循环),所以时间复杂度为
。
代码
#include <iostream>
#include <stdio.h>
using namespace std;
#define MAX_SIZE 100
char field[MAX_SIZE][MAX_SIZE+1];
void dfs(int x, int y, int n, int m){
field[x][y] = '*'; //把当前位置替换成'*'
for(int dx=-1; dx<=1; dx++){ //循环遍历8个方向
for(int dy=-1; dy<=1; dy++){
int nx = x + dx, ny = y + dy; //下一个位置
if(0 <= nx && nx < n && 0 <= ny && ny < m && field[nx][ny] == 'W')
dfs(nx, ny, n, m); //若满足条件,再次进行dfs
}
}
}
int main(){
int n, m, res = 0;
scanf("%d %d", &n, &m);
for(int i=0; i<n; i++)
scanf("%s", field[i]);
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
if(field[i][j] == 'W'){
dfs(i, j, n, m); //满足条件,进行dfs
res++;
}
}
}
printf("%d\n", res);
return 0;
}