问题
https://vjudge.net/problem/UVA-1330
分析
单调栈的使用,依此遍历每一行,同时每一行开始维护两个单调栈,确定以一个格子的对应列的高度构建矩形,向左边和右边可以扩展的最大范围,也就是宽度
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
typedef long long LL;
const int maxn=1000+5;
int m,n,kase=0,num[maxn],s[maxn],p,L[maxn],R[maxn];
char g[maxn][maxn],ch;
int main(void){
scanf("%d",&kase);
while(kase--){
int ans=0;
scanf("%d%d",&m,&n);
for(int i=0;i<m;++i){
for(int j=0;j<n;++j){
while((ch=getchar()) && ch!='F' && ch!='R');
g[i][j]=ch;
}
}
memset(num,0,sizeof(num));
for(int i=0;i<m;++i){
//计算每列中上面累积的连续的F的数量
for(int j=0;j<n;++j){
if(g[i][j]=='F') ++num[j];
else num[j]=0;
}
p=0; //清空栈,然后记录L和R的结果在数组中(确定高度后,左边,右边的最大宽度)
//高度是num[j],先计算左边的
for(int j=0;j<n;++j){
while(p>0 && num[s[p]]>=num[j]) --p;
if(p==0) L[j]=0;
else L[j]=s[p]+1;
s[++p]=j;
}
//计算右边,栈中只记录编号
p=0;
for(int j=n-1;j>=0;--j){
while(p>0 && num[s[p]]>=num[j]) --p;
if(p==0) R[j]=n-1;
else R[j]=s[p]-1;
s[++p]=j;
}
for(int j=0;j<n;++j)
ans=max(ans,num[j]*(R[j]-L[j]+1));
}
printf("%d\n",ans*3);
}
return 0;
}