题意:给定一个n*m的矩阵,其中一些格子是空地"F",另外一些是障碍"R",找出一个由F构成的面积最大的矩阵,并输出其面积乘以3的结果
我们把每个格子向上延伸的连续空格看成连续的一段线,用up[i][j]表示格子的线的长度
l[i][j],r[i][j]分别为格子向左,向右运动的极限位置,记录的是这个格子的线能向左/右到达的最小/大的列数
这样每个格子都对应着一个高度为up[i][j],左右边界为l[l][r],r[i][j]的矩形了
用lo表示当前列和在当前格子左边离得最近的障碍,ro表示当前列和在当前格子右边离得最近的障碍
up[i][j]=up[i-1][j]+1
l[i][j]=max(lo+1,l[i-1][j])
r[i][j]=min(ro-1,r[i-1][j])
维护lo和ro要从左/右到右/左讨论
然后注意一下边界处理
当(i,j)不是空格时,up[i][j]=l[i][j]=0,但是r[i][j]不能赋0,因为r[i][j]数组求的是min,赋值为0会影响结果
总之只要up,l,r三个数组有一个为0就表明不能构成矩形了
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=1005;
int n,m,t,l[maxn][maxn],r[maxn][maxn],up[maxn][maxn];
bool s[maxn][maxn];
char ch;
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
int i,j,ans=0;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++){
ch=getchar();
while(ch!='F'&&ch!='R')ch=getchar();
s[i][j]= ch=='R';
}
for(i=1;i<=n;i++){
int lo=0,ro=m+1;
for(j=1;j<=m;j++)
if(s[i][j])up[i][j]=l[i][j]=0,lo=j;
else {
up[i][j]= i==1?1:up[i-1][j]+1;
l[i][j]= i==1?lo+1:max(lo+1,l[i-1][j]);
}
for(j=m;j;j--)
if(s[i][j])r[i][j]=m+1,ro=j;
else r[i][j]= i==1?ro-1:min(ro-1,r[i-1][j]);
}
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
ans=max(ans,up[i][j]*(r[i][j]-l[i][j]+1));
printf("%d\n",ans*3);
}
}