1. 题目解析与算法思路
这道题目描述了一个N×M的网格土地,每个格子有各自的高度。降雨后,水会积聚在低洼处,我们需要计算整个土地最多能积存多少立方英寸的水。这实际上是一个经典的"接雨水"问题的二维扩展版本。
1.1 问题建模
我们可以将这个问题建模为一个二维的高度场积水问题。想象一下,当水从外部流入时,它会从四周最低的点开始渗透。只有当四周的高度都高于某个点时,这个点才能积水。
关键观察点:
- 水会从土地边缘流出,所以边缘的格子无法积水
- 一个内部格子能积水的高度取决于它到边缘的路径上的最低高度(即所谓的"木桶效应")
- 积水量等于每个格子能积水的高度之和
1.2 算法选择
常见的解决思路有几种:
- 优先队列+BFS(类似Dijkstra算法)
- 逐层DFS/BFS模拟水位上升
- 动态规划计算每个格子的边界最小值
这里我们选择第二种方法——逐层DFS模拟水位上升,因为:
- 直观易懂,容易实现
- 对于N,M≤100的数据规模完全足够
- 可以很好地利用题目中高度范围有限(1-10000)的特性
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心算法实现详解
2.1 预处理高度信息
cpp复制int h[105][105],vis[105][105];
int t[10005];
int n,m,mx,mn;
// 读取输入并预处理
read(n);read(m);
mn = 10005;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
read(h[i][j]);
mx = max(mx,h[i][j]);
mn = min(mn,h[i][j]);
t[h[i][j]]++; // 统计每个高度出现的次数
}
}
// 计算高度大于等于i的格子数量
for(int i=mx;i>=mn;i--){
t[i] += t[i+1];
}
这段代码做了几件重要的事情:
- 读取输入数据并存储到h数组中
- 记录全局最大高度mx和最小高度mn
- 统计每个高度出现的次数到t数组
- 通过后缀和技巧,快速计算高度≥i的格子数量
提示:使用后缀和可以让我们在O(1)时间
