1. 题目解析与算法选择
今天遇到一个有趣的算法题目——数池塘问题。题目描述很简单:给定一个N×M的二维矩阵,每个格子要么是'W'表示有水,要么是'.'表示陆地。我们需要统计其中"池塘"的数量,这里的池塘定义为由相邻'W'组成的区域,相邻包括八个方向(上下左右加四个对角线)。
这个问题本质上是一个经典的连通区域计数问题,在图像处理、游戏开发等领域都有广泛应用。解决这类问题最常用的两种算法就是深度优先搜索(DFS)和广度优先搜索(BFS),它们都属于Flood Fill(泛洪填充)算法的具体实现。
提示:Flood Fill算法就像用油漆桶工具填充一个封闭区域,它会从起点开始,向四周扩散填充,直到遇到边界为止。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 深度优先搜索(DFS)解法详解
2.1 DFS核心思路
DFS的实现思路非常直观:从遇到的第一个'W'开始,递归地向八个方向探索,把所有连通的'W'都标记为已访问(这里通过改为'.'实现),这样就完成了一个池塘的标记,计数器加1。
cpp复制void dfs(int x,int y) {
mp[x][y]='.'; // 标记为已访问
for(int i=0; i<8; i++) {
int tx=x+dx[i];
int ty=y+dy[i];
if(mp[tx][ty]=='W') {
dfs(tx,ty); // 递归处理相邻格子
}
}
}
2.2 方向数组技巧
这里使用了一个小技巧——方向数组,它定义了八个方向的坐标偏移量:
cpp复制int dx[] = {1,1,0,-1,-1,-1,0,1}; // x方向偏移
int dy[] = {0,1,1,1,0,-1,-1,-1}; // y方向偏移
这种写法比写八个if语句更简洁,也更容易修改。方向顺序通常是从正右开始顺时针旋转,但具体顺序不影响结果。
2.3 边界处理注意事项
在实际代码中,我们需要注意数组越界问题。DFS版本中虽然没有显式检查边界,但题目保证输入数据边缘都是'.',所以可以省略边界检查。但在更严格的场景下,应该添加:
cpp复制if(tx<0 || ty<0 || tx>
