1 条题解

  • 0
    @ 2025-11-5 15:29:39
    • 尝试从上到下枚举每一行 ii,当做最终矩形的下底
    • 从第 ii 行开始,计算每一列连续往上的 11 的个数
    • 那么问题转化为 LS1199. 【普及】柱状图中最大的矩形
    • 时间复杂度:O(nm)O(nm)
    #include <bits/stdc++.h>
    using namespace std;
    
    int gao(vector<int>& h) {
        int n = h.size();
        vector<int> L(n, -1);  // L[i]: 表示 i 左边第一个比 h[i] 小的下标
        vector<int> R(n, n);   // R[i]: 表示 i 右边第一个比 h[i] 小的下标
        
        int e = 0;
        vector<int> s(n);
        
        // 只扫一遍, 同时确定 L 和 R
        for (int i = 0; i < n; i++) {
            // 出栈的时候确定右边第一个比自己小的
            while (e > 0 && h[s[e - 1]] > h[i]) R[s[--e]] = i;
            
            // 入栈的时候确定左边第一个比自己小的
            if (e > 0) L[i] = s[e - 1];
            s[e++] = i;
        }
        // for (int i = 0; i < n; i++) cout << L[i] << " \n"[i == n - 1];
        // for (int i = 0; i < n; i++) cout << R[i] << " \n"[i == n - 1];
        int ans = 0;
        for (int i = 0; i < n; i++) ans = max(ans, h[i] * (R[i] - L[i] - 1));
        return ans;
    }
    
    int cal(vector<string>& g) {
        int n = g.size(), m = g[0].size(), ans = 0;
        vector<int> h(m, 0);
    
        // 枚举每一行, 当做最终矩形的下底
        for (int i = 0; i < n; i++) {
            // 对每一列找到连续向上的 1 的个数
            for (int j = 0; j < m; j++) {
                if (g[i][j] == '0') h[j] = 0;
                else h[j] += 1;
            }
            ans = max(ans, gao(h));
        }
        return ans;
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
    
        int n, m;
        cin >> n >> m;
        vector<string> g(n);
        for (int i = 0; i < n; i++) cin >> g[i];
        cout << cal(g) << '\n';
    
        return 0;
    }
    
    • 1

    信息

    ID
    161
    时间
    100ms
    内存
    32MiB
    难度
    5
    标签
    递交数
    32
    已通过
    15
    上传者