LA3029

题目大意:
求空地F的最大矩形,求最大子矩阵

思路:
用三个数组up,l,r分别表示举行的高度,左边界,右边界。
lo 表示左边最近障碍格的列编号。
ro表示右边最近障碍格的列编号。
先从左到右维护左边界。
如果是有障碍的话 那么up [i][j] = 0,l[i][j] = 0,lo = j;
当i是第一行的时候
如果没有障碍的话 那么up[i][j] = 1,l[i][j] = lo + 1;
如果不是第一行而且没有障碍的话
up = up[i - 1][j] + 1;
l[i][j] = max(l[i - 1][j],lo + 1);

从右到左维护右边界。
如果有障碍的话
r[i][j] = n; ro = j;
如果没有障碍的话
第一行:
r[i][j] = ro - 1;
否则
r[i][j] = min(ro - 1,r[i - 1][j]);

代码:

#include <iostream>
using namespace std;
#include <stdio.h>
#include <cstring>
#include <algorithm>

const int maxn = 1000;
int map[maxn][maxn],l[maxn][maxn],r[maxn][maxn],up[maxn][maxn];
int main() {

    int T;
    scanf("%d",&T);
    int m,n;
    char c;
    while(T--) {
        scanf("%d %d",&m,&n);
        for(int i = 0 ; i < m; i++) {
            for(int j = 0; j < n ; j++) {
                //scanf("%c",&c);
                c = getchar();
                while(c != 'R' && c!='F') c = getchar();
                if(c == 'F') map[i][j] = 0;
                else
                    map[i][j] = 1;
            }
        }
        int lo = 0,ro = n;
        int ans = 0;
        for(int i = 0; i < m; i++) {
            lo = -1,ro = n;
            for(int j = 0; j <n ; j++) {
            //  if(i == 0) {
                    if(map[i][j] == 1) {
                        lo = j;
                        up[i][j] = 0;
                        l[i][j] = 0;
                    }
                    else {
                        if(i == 0) {
                        up[i][j] = 1;
                        l[i][j] = lo +1;
                        }
                        else {
                            up[i][j] = up[i - 1][j] + 1;
                            l[i][j] = max (lo + 1,l[i - 1][j]);
                        }
                    }
            }
            for(int j = n - 1; j >= 0; j--) {
                if(map[i][j] == 1) {
                    ro = j;
                //  up[i][j] = 0;
                    r[i][j] = n;
                }
                else {
                    if(i == 0) {
                //      up[i][j] = 1;
                        r[i][j] = ro - 1;
                    }
                    else {
                    //  up[i][j] = up[i - 1][j] + 1;
                        r[i][j] = min(ro - 1,r[i - 1][j]);
                    }
                }
                ans = max(ans, (r[i][j] - l[i][j] + 1) * up[i][j]);
            }
        }
            printf("%d\n",ans*3);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值