题目大意:
求空地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;
}