LA 3029 City Game

一个n x m的矩阵中有很多障碍物.

现求一个最大的且不包含障碍物的子矩阵.

把每个格子向上延伸到障碍或者边界的连续的空格看做一条线段, 则对于该格来说, 它对应的一个子矩阵子矩阵即为这条线段左右可移动到的边界.

又知任何一个矩阵均可以由它最下层的某个对应线段长度恰好为矩形高度的格子表示.

故对于每一个格子, 求出其对应矩阵即可(即其对应线段左右移动的最远地点)

可推得:

up[i][j] = up[i-1][j] + 1, 当格子为障碍物或者边界时, up为0

left[i][j] = max(left[i-1][j], lo+1) 其中lo为当前格子所在行左侧最靠近的障碍坐标.

同理有

right[i][j] = min(right[i-1][j], ro-1)

/*
 * LA3029.cpp
 *
 *  Created on: Jun 2, 2013
 *      Author: root
 */
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 1010;

int grid[maxn][maxn];

int up[maxn][maxn], left1[maxn][maxn], right1[maxn][maxn];
int n, m;
int main() {
	int T;
	scanf("%d", &T);
	while(T--){
		scanf("%d%d", &m, &n);
		for(int i = 0; i < m; ++i){
			for(int j = 0; j < n; ++j){
				char ch = getchar();
				while(ch != 'F' && ch != 'R') ch = getchar();
				grid[i][j] = ch == 'F' ? 0 : 1;
			}
		}
		int ans = 0, lo, ro;
		for(int i = 0; i < m; ++i){
			lo = -1, ro = n;
			for(int j = 0; j < n; ++j){
				if(grid[i][j] == 1){
					up[i][j] = left1[i][j] = 0;
					lo = j;
				}else{
					up[i][j] = i == 0 ? 1 : up[i - 1][j] + 1;
					left1[i][j] = i == 0 ? lo + 1 : max(left1[i - 1][j], lo + 1);
				}
			}
			for(int j = n - 1; j >= 0; --j){
				if (grid[i][j] == 1) {
					right1[i][j] = n;
					ro = j;
				} else {
					right1[i][j] = i == 0 ? ro - 1 : min(right1[i - 1][j], ro - 1);
					ans = max(ans, up[i][j] * (right1[i][j] - left1[i][j] + 1));
				}
			}
		}
		printf("%d\n", ans * 3);
	}
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值