1. 题目背景与问题描述
农夫约翰的农场被表示为一个N×M的矩形网格,每个网格可能是积水('W')或干燥('.')。一场大雨过后,我们需要统计农场中形成的池塘数量。这里的池塘定义为:由相邻的'W'组成的连通区域,其中"相邻"指的是上下左右四个方向(四连通)。
这个问题属于典型的连通区域计数问题,在图论和图像处理中非常常见。类似的应用场景还包括:
- 计算岛屿数量(LeetCode经典题目)
- 图像处理中的连通区域分析
- 游戏开发中的地图区域划分
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算法选择与思路分析
2.1 Flood Fill算法原理
Flood Fill(洪水填充)算法是解决这类连通区域问题的标准解法。它的核心思想是从一个种子点开始,向四周扩散填充,直到遇到边界或不符合条件的区域为止。
算法特点:
- 时间复杂度:O(N×M),每个网格最多被访问一次
- 空间复杂度:取决于实现方式(DFS的递归深度或BFS的队列大小)
- 实现方式:深度优先搜索(DFS)或广度优先搜索(BFS)
2.2 四方向与八方向的差异
题目特别强调使用四方向(上下左右)而非八方向(包含对角线),这会影响连通性的判断:
- 四方向:更严格的连通定义,池塘形状更"紧凑"
- 八方向:更宽松的连通定义,可能将更多区域连接在一起
在实际应用中:
- 四方向适合模拟严格物理隔离的区域
- 八方向适合模拟可以斜向渗透的场景(如液体扩散)
3. 代码实现详解
3.1 DFS实现解析
cpp复制#include <bits/stdc++.h>
using namespace std;
const int N=1e3+5;
char mp[N][N];
int dx[]= {1,0,-1,0}; // 四方向移动:下、右、上、左
int dy[]= {0,1,0,-1};
int n,m,ans;
void dfs(int x,int y) {
mp[x][y]='.'; // 标记为已访问
for(int i=0; i<4; i++) {
int tx=x+dx[i];
int ty=y+dy[i];
if(mp[tx][ty]=='W') {
dfs(tx,ty); // 递归访问相邻W
}
}
}
int main() {
cin>>n>>m;
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
cin>>mp[i][j];
}
}
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
if(mp[i
