Live Archive 3029 City Game

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值