一遍AC 非常开心
代码注释写的很清楚 不会做先去做131题直方图中的最大矩形(自己搜,这里不能跳转)
// Created by Jonny; on 24-11-23.
#include <bits/stdc++.h>
using namespace std;
const int N=2000;
int n,m;
int a[N][N];
//单调栈:记录一个F左右两边第一个纵向连续F比自己矮的F的坐标(有R默认高度0 纵向从这行往上n个f则高度为f)
int q[N],l[N][N],r[N][N];
int s[N][N];//记录一个a[i][j]处往上有几个连续的F
int main() {
//初始化边缘为0 即为R 避免计算进入高度
memset(a,0,sizeof(a));
memset(s,0,sizeof(s));
cin>>n>>m;
//是F则为1 是R则为0
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
char c;
cin>>c;
if(c=='F') a[i][j]=1;
else if(c=='R') a[i][j]=0;
}
}
//第一行如果是F则高度为1 反之高度0 初始化第一行
for(int i=1;i<=m;i++) {
if(a[1][i]==1) s[1][i]=1;
else s[1][i]=0;
}
for(int i=2;i<=n;i++) {
for(int j=1;j<=m;j++) {
//无论与同列上一个是否相等 我们是先遍历的上边 即将如果是R则一定被赋值为0(看下面else)如果不是则有高度值 就是加0或者加高度的问题
if(a[i][j]==1) s[i][j]+=s[i-1][j]+1;
else s[i][j]=0;
}
}//得到的这个高度值是不是有点眼熟?就是ACWing131题直方图那个一维数组的模型
//O(n*m)<=4e6
for(int i=1;i<=n;i++) {
//现在就只看i指定的某一行 s[][j] s[][0]=-1,s[][m+1]=-1,now=0,q[now]=0 or m+1
s[i][0]=-1,s[i][m+1]=-1;
int now=0;
q[now]=0;
//计算左边
for(int j=1;j<=m;j++) {
while(s[i][q[now]]>=s[i][j]) now--;
l[i][j]=q[now];
q[++now]=j;
}
//计算右边
now=0;
q[now]=m+1;
for(int j=m;j>=1;j--) {
while(s[i][q[now]]>=s[i][j]) now--;
r[i][j]=q[now];
q[++now]=j;
}
}
long long ans=0;
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
if(s[i][j]==0) continue;
long long col=r[i][j]-l[i][j]-1;
ans=max(ans,col*s[i][j]);
}
}
cout<<3*ans<<endl;
return 0;
}