Live Archive 3029 City Game

来源:互联网 发布:替代 usleep windows 编辑:程序博客网 时间:2024/06/11 02:02

题意:给定一个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);}}



0 0
原创粉丝点击