这个题感觉很好。将时间转为空间,巧妙降维。
思路参考了入门指南。
值得一提的是关于up、left、right这三个数组的递推。up很好想。left的时候要注意,如果某一列的up小于等于左邻的up,这说明该列悬线是可以左移到左邻这列可到的最远左边界的,否则该列可达最远左边界就是当前这列本身。right需要从右往左递推,思路类似。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#define ll long long
#define INF 2139062143
#define inf -2139062144
#define MOD 20071027
#define MAXN 1005
using namespace std;
char grid[MAXN][MAXN];
int up[MAXN][MAXN],l[MAXN][MAXN],r[MAXN][MAXN];
int n,m;
void Init()
{
memset(up,0,sizeof(up));
memset(l,0,sizeof(l));
memset(r,0,sizeof(r));
for(int i=1; i<=n; ++i)
{
for(int j=1; j<=m; ++j)
if(grid[i][j]=='R') up[i][j]=0;
else up[i][j]=up[i-1][j]+1;
l[i][1]=1;
for(int j=2; j<=m; ++j)
if(up[i][j]<=up[i][j-1]) l[i][j]=l[i][j-1];
else l[i][j]=j;
r[i][m]=m;
for(int j=m-1; j>=1; --j)
if(up[i][j]<=up[i][j+1]) r[i][j]=r[i][j+1];
else r[i][j]=j;
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1; i<=n; ++i)
{
for(int j=1; j<=m; ++j)
{
char c=getchar();
while(c!='F'&&c!='R')c=getchar();
grid[i][j]=c;
}
}
Init();
int ans=0;
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
if(grid[i][j]=='F')
ans=max(ans,up[i][j]*(r[i][j]-l[i][j]+1));
printf("%d\n",3*ans);
}
return 0;
}