题目
简化题意
找一个最大的全都是 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 << '
';
return 0;
}