作者:岸芷汀兰
一、题目:
二、思路:
单调栈裸题。
预处理:s[i][j]表示(i,j)向上有几个连续的”F”。
需要用单调栈统计两个数组:l[i][j]表示s[i][j]的左边第一个比s[i][j]小的位置,r[i][j]表示s[i][j]的右边第一个比s[i][j]小的位置。
那么此时矩形的面积就是(r[i][j]-1-l[i][j])*s[i][j]。
具体细节看代码。
写得太丑。
三、代码:
#include<iostream>
#include<cstdio>
#include<stack>
#include<algorithm>
using namespace std;
inline int read(void) {
int x = 0, f = 1; char ch = getchar();
while (ch<'0' || ch>'9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0'&&ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return f * x;
}
const int maxn = 1005;
int n, m, map[maxn][maxn], s[maxn][maxn], l[maxn][maxn], r[maxn][maxn], ans;
stack<int>monotonous;
inline void clear(void) {
while (monotonous.size())monotonous.pop(); return;
}
int main()
{
n = read(); m = read();
for (register int i = 1; i <= n; i++) {
for (register int j = 1; j <= m; j++) {
char ch; cin >> ch;
map[i][j] = (ch == 'F' ? 1 : 0);
}
}
for (register int i = 1; i <= n; i++) {
for (register int j = 1; j <= m; j++) {
if (map[i][j]) {
s[i][j] = s[i - 1][j] + 1;
}
}
}
for (register int i = 1; i <= n; i++) {
clear();
for (register int j = 1; j <= m; j++) {
if (monotonous.empty()) {
monotonous.push(j); l[i][j] = 0;
}
else {
while (monotonous.size() && s[i][j] <= s[i][monotonous.top()])monotonous.pop();
if (monotonous.size())l[i][j] = monotonous.top();
else l[i][j] = 0;
monotonous.push(j);
}
}
clear();
for (register int j = m; j >= 1; j--) {
if (monotonous.empty()) {
monotonous.push(j); r[i][j] = m + 1;
}
else {
while (monotonous.size() && s[i][j] <= s[i][monotonous.top()])monotonous.pop();
if (monotonous.size())r[i][j] = monotonous.top();
else r[i][j] = m + 1;
monotonous.push(j);
}
}
}
for (register int i = 1; i <= n; i++) {
for (register int j = 1; j <= m; j++) {
if (!s[i][j])continue;
int area = ((r[i][j] - 1) - l[i][j])*s[i][j];
ans = max(ans, area);
}
}
printf("%d\n", ans * 3);
return 0;
}