这题先进行转换,F面积最大就是在以每一行为底找F的最大矩形
在在f[i][j]中存下(i,j)这个点上面的连续的F的个数
在第i行中利用单调栈求出每个f[i][j]为高的左边界和右边界
进而f[i][j]*(right-left+1)就是该矩形的面积
单调栈:先考虑左边界,是要找到从右往左第一个f[i][j-k][HTML_REMOVED]=f[i][j],则永远不会再找到f[i][j-k],则f[i][j-k]是无用的,将f[i][j-k]直接出站
左右两遍扫描o(m)求出左右边界
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;
typedef pair<int,int> PII;
const int N=1010;
int n,m,f[N][N],ans,lr[2][N];
char s[N][N];
void get(int x,int k)
{
stack<PII> s1;
s1.push({-1,0});
for(int j=1;j<=m;j++)
{
while(s1.top().first>=f[x][j])s1.pop();
lr[k][j]=s1.top().second+1;
s1.push({f[x][j],j});
}
}
void work(int x)
{
get(x,0);//同一函数利用翻转多用减少代码量,但翻转后的下标需要仔细考虑
reverse(f[x]+1,f[x]+1+m);
get(x,1);
reverse(f[x]+1,f[x]+1+m);
for(int i=1;i<=m;i++)
{
int left = lr[0][i];
int right = m - lr[1][m-i+1] + 1;
ans=max(ans,(right-left+1) * f[x][i] );
}
}
int main()
{
// freopen("123.txt","r",stdin);
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin >> s[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(s[i][j]=='F')f[i][j]=f[i-1][j]+1;
for(int i=1;i<=n;i++)work(i);
cout<<ans*3;
return 0;
}