酷代码 AI
菜单
服务商
DeepSeek字节豆包
更多选项

全零子矩阵计数算法解析及修正

我来帮你分析这段代码的问题并修正。 ## 🔍 问题分析 这段代码尝试用**单调栈**方法计算所有可能的矩形数量,但存在几个关键错误: ### ❌ 主要错误 1. **高度计算方式错误**:不是简单的非*就加1,而是需要统计连续`.`的高度 2. **矩形计数逻辑错误**:题目要求统计所有不含`*`的矩形,不是柱状图中的矩形 3. **计数重复问题**:单调栈方法容易造成重复计数 ## 📐 正确解法思路 这是一个典型的**统计全0子矩阵个数**问题,可以用**动态规划+单调栈**解决: ```cpp #include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(0); int n, m; cin >> n >> m; vector<vector<char>> grid(n, vector<char>(m)); for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { cin >> grid[i][j]; } } // height[j] 表示以当前行作为底边,从下往上连续'.'的个数 vector<int> height(m, 0); long long total = 0; for (int i = 0; i < n; ++i) { // 更新每一列的连续高度 for (int j = 0; j < m; ++j) { if (grid[i][j] == '.') { height[j]++; } else { height[j] = 0; } } // 使用单调栈统计以当前行为底边的矩形个数 stack<int> st; // 使用前缀和方法更简单 vector<int> left(m, -1), right(m, m); // 计算左边界 for (int j = 0; j < m; ++j) { while (!st.empty() && height[st.top()] >= height[j]) { st.pop(); } left[j] = st.empty() ? -1 : st.top(); st.push(j); } // 清空栈,计算右边界 while (!st.empty()) st.pop(); for (int j = m - 1; j >= 0; --j) { while (!st.empty() && height[st.top()] > height[j]) { st.pop(); } right[j] = st.empty() ? m : st.top(); st.push(j); } // 统计以当前行为底边的矩形数量 for (int j = 0; j < m; ++j) { if (height[j] > 0) { // 以height[j]作为矩形高度,可选择的宽度为 (j - left[j]) * (right[j] - j) long long leftWays = j - left[j]; long long rightWays = right[j] - j; total += height[j] * leftWays * rightWays; } } } cout << total << "\n"; return 0; } ``` ## 📊 算法思路说明 1. **逐行处理**:从上到下遍历每一行,作为矩形的底边 2. **维护高度数组**:`height[j]`表示从当前行向上连续`.`的个数 3. **单调栈找边界**: - `left[j]`:左边第一个高度小于`height[j]`的列索引 - `right[j]`:右边第一个高度小于`height[j]`的列索引 4. **计算矩形数**:对于每个`height[j] > 0`的列,可以形成的高度为1到`height[j]`,宽度为`(j - left[j]) * (right[j] - j)`个可能的矩形 ## ⚠️ 关键注意事项 1. **数据类型**:结果可能很大,使用`long long` 2. **边界处理**:左右边界分别设置为`-1`和`m` 3. **高度计算**:遇到`*`时重置为0,而不是简单累加 ## 💡 优化建议 - 可以添加`#include <iostream>`和`#include <vector>`替代`bits/stdc++.h`以提高编译速度 - 考虑使用`#pragma GCC optimize("O3")`优化性能 - 对于大规模数据(1000×1000),当前算法复杂度为O(n×m),已经是最优解 ######[AI写代码神器 | 1011点数解答 | 2026-06-14 20:01:32]

相关提问
本站限时免费提问中
实用工具查看更多
Linux在线手册 [开发类]
Jquery在线手册 [开发类]
今日油价 [生活类]
图片互转base64 [开发类]
时间转换器 [开发类]