「题解」洛谷 P4147 玉蟾宫

题目

P4147 玉蟾宫

简化题意

找一个最大的全都是 F 的矩形。

思路

单调栈,悬线法。

计算出每个点向上最多能扩展多少,变成了直方图求最大矩形问题。

Code

悬线法:

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 1001

int max(int a, int b) { return a > b ? a : b; }

int n, m, ans, up[M][M], l[M], r[M];
char map[M][M];

int main() {
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            std::cin >> map[i][j];
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            l[j] = r[j] = j;
            if (map[i][j] == 'R') up[i][j] = 0;
            else up[i][j] = up[i - 1][j] + 1;
        }
        for (int j = 1; j <= m; ++j) {
            while (l[j] > 1 && up[i][j] <= up[i][l[j] - 1]) l[j] = l[l[j] - 1];
        }
        for (int j = m; j >= 1; --j) {
            while (r[j] < m && up[i][j] <= up[i][r[j] + 1]) r[j] = r[r[j] + 1];
        }
        for (int j = 1; j <= m; ++j) {
            ans = max(ans, (r[j] - l[j] + 1) * up[i][j]);
        }
    }
    std::cout << 3 * ans;
    return 0;
}

单调栈:

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 1518

int max(int a, int b) { return a > b ? a : b; }

int n, m, ans, top, s[M], w[M], up[M][M];
char map[M][M];

int main() {
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            std::cin >> map[i][j];
            if (map[i][j] != 'F') up[i][j] = 0;
            else up[i][j] = up[i - 1][j] + 1;
        }
    }
    for (int i = 1; i <= n; ++i) {
        top = 0;
        s[++top] = up[i][1], w[top] = 1;
        for (int j = 2; j <= m + 1; ++j) {
            if (up[i][j] > s[top]) {
                s[++top] = up[i][j];
                w[top] = 1;
            }
            else {
                int len = 0;
                while (top && s[top] >= up[i][j]) {
                    len += w[top];
                    ans = max(ans, len * s[top]);
                    --top;
                }
                s[++top] = up[i][j], w[top] = len + 1;
            }
        }
    }
    std::cout << 3 * ans << '\n';
    return 0;
}
posted @ 2020-09-11 10:48  yu__xuan  阅读(75)  评论(0编辑  收藏  举报