牛客多校第二场 H.Second Large Rectangle(次大全1子矩阵)

给出一个01矩阵,求次大的全1子矩阵。
求最大是经典的单调栈O(m*n)做法,但是求次大的时候就会出现各种麻烦。
算是成功签到了。
比起求最大,同时维护一个次大,但是这样会wa,还需要记录最大子矩阵宽高里最小的那一个,然后用最大子矩阵减去min(宽,高),这是为了考虑次大在最大内部的情况。

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn = 1e3 + 5;
const int inf = maxn * maxn;
/*
4 5
11011
11111
10101
11111

 */

int n, m;
char s[maxn][maxn];
int maxArea = 0, maxArea2 = 0;
pair<int, int> kk;

void getMaxMartrixFromBottom(vector<int> height) {
    vector<int> stack;
    int i = 0;
    for (; i < m; ++i) {
        while (!stack.empty() && height[i] <= height[stack.back()]) {
            int j = stack.back();
            stack.pop_back();
            int k = stack.empty() ? -1 : stack.back();
            int curArea = (i - k - 1) * height[j];
            //maxArea = Math.max(maxArea, curArea);
            if (curArea >= maxArea) {
                maxArea2 = maxArea;
                maxArea = curArea;
                kk = {(i - k - 1), height[j]};
            } else if (curArea > maxArea2) {
                maxArea2 = curArea;
            }
        }
        stack.push_back(i);
    }
    while (!stack.empty()) {
        int j = stack.back();
        stack.pop_back();
        int k = stack.empty() ? -1 : stack.back();
        int curArea = (i - k - 1) * height[j];
        //maxArea = Math.max(maxArea, curArea);
        if (curArea >= maxArea) {
            maxArea2 = maxArea;
            maxArea = curArea;
            kk = {(i - k - 1), height[j]};
        } else if (curArea > maxArea2) {
            maxArea2 = curArea;
        }
    }
}

void getMaxMartrix() {
    vector<int> height(m + 5, 0);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            height[j] = s[i][j] == '0' ? 0 : height[j] + 1;
        }
        //maxArea = max(maxArea, getMaxMartrixFromBottom(height));
        getMaxMartrixFromBottom(height);
    }
}

int main() {
    while (~scanf("%d%d", &n, &m)) {
        maxArea = maxArea2 = 0;
        for (int i = 0; i < n; ++i) {
            scanf("%s", s[i]);
        }
        getMaxMartrix();
//        maxArea2 = max(maxArea2, maxArea - min(kk.first, kk.second));
        printf("%d\n", maxArea2);
    }
    return 0;
}
发布了156 篇原创文章 · 获赞 20 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/Cymbals/article/details/96643733