玉蟾宫
题目
题目背景
有一天,小猫 rainbow 和 freda 来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地。
题目描述
这片土地被分成 N × M N\times M N×M 个格子,每个格子里写着 ‘R’ 或者 ‘F’,R 代表这块土地被赐予了 rainbow,F 代表这块土地被赐予了 freda。
现在 freda 要在这里卖萌。。。它要找一块矩形土地,要求这片土地都标着 ‘F’ 并且面积最大。
但是 rainbow 和 freda 的 OI 水平都弱爆了,找不出这块土地,而蓝兔也想看 freda 卖萌(她显然是不会编程的……),所以它们决定,如果你找到的土地面积为 S S S,它们每人给你 S S S 两银子。
输入格式
第一行两个整数 N N N, M M M,表示矩形土地有 N N N 行 M M M 列。
接下来 N N N 行,每行 M M M 个用空格隔开的字符 ‘F’ 或 ‘R’,描述了矩形土地。
输出格式
输出一个整数,表示你能得到多少银子,即 ( 3 × 最大 ’F’ 矩形土地面积 3\times \text{最大 'F' 矩形土地面积} 3×最大 ’F’ 矩形土地面积) 的值。
样例 #1
样例输入 #1
5 6
R F F F F F
F F F F F F
R R R F F F
F F F F F F
F F F F F F
样例输出 #1
45
提示
对于
50
%
50\%
50% 的数据,
1
≤
N
,
M
≤
200
1 \leq N, M \leq 200
1≤N,M≤200。
对于
100
%
100\%
100% 的数据,
1
≤
N
,
M
≤
1000
1 \leq N, M \leq 1000
1≤N,M≤1000。
题解
本题使用悬线法。
悬线法,顾名思义,是统计了每个节点向上所能扩展的最大值。这里记为 up数组。
同时,我们还要统计每个点向左和向右所能扩展的最大值,这里记为 le数组和 ri 数组。
对于每个 le[i][j] , ri[i][j] 和 up[i][j],如果 i >1,那么可以得出递推式:
le[i][j] = max(le[i][j], le[i-1][j]);
ri[i][j] = min(ri[i][j], ri[i-1][j]);
up[i][j] += up[i-1][j];
这样我们就可以很轻松地解决这道题了。
Code:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 1e3 + 5;
const int mod = 10007;
int n, m, ans;
int le[maxn][maxn], ri[maxn][maxn], up[maxn][maxn];
char maze[maxn][maxn];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) {
cin >> maze[i][j];
le[i][j] = ri[i][j] = j;//别忘了初始化
up[i][j] = 1;
}
for(int i = 1; i <= n; i++)
for(int j = 2; j <= m; j++) {
if(maze[i][j] == 'F' && maze[i][j-1] == 'F') {
le[i][j] = le[i][j-1];//将l数组向左初始化
}
}
for(int i = 1; i <= n; i++)
for(int j = m-1; j >= 1; j--) {
if(maze[i][j] == 'F' && maze[i][j+1] == 'F') {
ri[i][j] = ri[i][j+1];//将r数组向右初始化
}
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) {
if(maze[i][j] != 'F') continue;
if(i > 1 && maze[i-1][j] == 'F') {//满足条件,调整le和ri
le[i][j] = max(le[i][j], le[i-1][j]);
ri[i][j] = min(ri[i][j], ri[i-1][j]);
up[i][j] += up[i-1][j];
}
ans = max(ans, (ri[i][j] - le[i][j] + 1) * up[i][j]);//长乘宽计算面积
}
cout << ans*3;
return 0;
}