思路:对每一个格子进行处理:计算包含它的最大矩形。
up[i][j]: 存储矩形的高;
left[i][j]: 存储矩形的左边界的列号;
right[i][j]:存储矩形的右边界的列号。
面积 = up[i][j] * ( right[i][j] - left[i][j] +1 )。
心得:即便是有了思路,写代码前也要在纸上画画,模拟模拟。否则就像代码中提示注意的地方,写成了0,估计debug半天也不知道错在哪了。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <stack>
#include <queue>
#include <set>
#include <map>
typedef long long ll;
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e3+10;
int mat[maxn][maxn],up[maxn][maxn];
int myleft[maxn][maxn],myright[maxn][maxn];
int m,n;
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%d %d",&m,&n);
char ch;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
ch=getchar();
while(ch!='R' && ch!='F')ch=getchar();
if(ch=='R')mat[i][j]=1;
else mat[i][j]=0;
}
}
/*
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
printf("%d ",mat[i][j] );
}
printf("\n");
}*/
int ans=0,i,j;
for(i=0;i<m;i++){//从上到下扫描
int lo=-1,ro=n;//lo表示左边障碍物的列号,ro同理。
for(j=0;j<n;j++){//从左到右扫描,处理up[][]和left[][]。
if(mat[i][j]==1){
lo=j;
up[i][j]=0;
myleft [i][j]=0;
}else{
up[i][j]=(i==0?1:up[i-1][j]+1);
myleft[i][j]=(i==0?lo+1:max(myleft[i-1][j],lo+1));// !!!
}
}
for(int j=n-1;j>=0;j--){//从右往左扫描,处理right[][]。
if(mat[i][j]==1){
ro=j;
myright[i][j]=n;//注意细节
}else{
myright[i][j]=(i==0?ro-1:min(myright[i-1][j],ro-1));// !!!
ans=max(ans,up[i][j]*(myright[i][j]-myleft[i][j]+1));
}
}
}
printf("%d\n",ans*3 );
}
return 0;
}