当前位置: 代码迷 >> 综合 >> City Game UVALive - 3029(扫描法)
  详细解决方案

City Game UVALive - 3029(扫描法)

热度:41   发布时间:2023-11-22 01:17:11.0

题目链接

https://vjudge.net/problem/UVALive-3029

题目

Bob is a strategy game programming specialist. In his new city building game the gaming environment
is as follows: a city is built up by areas, in which there are streets, trees, factories and buildings. There
is still some space in the area that is unoccupied. The strategic task of his game is to win as much
rent money from these free spaces. To win rent money you must erect buildings, that can only be
rectangular, as long and wide as you can. Bob is trying to find a way to build the biggest possible
building in each area. But he comes across some problems — he is not allowed to destroy already
existing buildings, trees, factories and streets in the area he is building in.
Each area has its width and length. The area is divided into a grid of equal square units. The rent
paid for each unit on which you’re building stands is 3$.
Your task is to help Bob solve this problem. The whole city is divided into K areas. Each one of
the areas is rectangular and has a different grid size with its own length M and width N. The existing
occupied units are marked with the symbol ‘R’. The unoccupied units are marked with the symbol ‘F’.

Input

The first line of the input file contains an integer K — determining the number of datasets. Next lines
contain the area descriptions. One description is defined in the following way: The first line contains
two integers-area length M ≤ 1000 and width N ≤ 1000, separated by a blank space. The next M
lines contain N symbols that mark the reserved or free grid units, separated by a blank space. The
symbols used are:
R - reserved unit
F - free unit
In the end of each area description there is a separating line.

Output

For each data set in the input file print on a separate line, on the standard output, the integer that
represents the profit obtained by erecting the largest building in the area encoded by the data set.

Sample Input

2
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
5 5
R R R R R
R R R R R
R R R R R
R R R R R
R R R R R

Sample Output

45
0

题意

给定一个N*M的矩阵,矩阵上一些是空地(F),一些是障碍(R)。求全由空地组成的最大子矩阵的面积,最后输出面积的三倍。

分析

对于矩阵上的每一个格子,求出其最上能到达的高度up[i][j];以穿过该格子的竖线向左扫描,求出竖线能到达的最左的位置的列数left[i][j];同理向右扫描,求出能到达的最右的位置的列数right[i][j].

递推求up,left,right:
up[i][j]=up[i-1][j]+1;
left[i][j]=max(left[i-1][j],lo+1);
lo为第i行第j列的左侧的最近的障碍的列数

代码

#include <cstdio>
#include <cstring>
#include <algorithm>using namespace std;const int maxn=1e3+100;
char a[maxn][maxn];
int up[maxn][maxn]; //矩形的高度
int left[maxn][maxn]; //最左侧所在的列数
int right[maxn][maxn]; //最右侧所在的列数int main()
{int T;scanf("%d",&T);while(T--){int N,M,ans=0;scanf("%d%d",&N,&M);//输入for(int i=0; i<N; i++){for(int j=0; j<M; j++){char c=getchar();while(c!='R' && c!='F')c=getchar();a[i][j]=c;}}for(int i=0; i<N; i++){int lo=-1;//从左到右更新for(int j=0; j<M; j++){//特殊情况if(a[i][j]=='R'){up[i][j]=left[i][j]=0;lo=j;}else{up[i][j]=i==0?1:up[i-1][j]+1;left[i][j]=i==0?lo+1:max(left[i-1][j],lo+1);}}int ro=M;//从右到左更新for(int j=M-1; j>=0; j--){if(a[i][j]=='R'){right[i][j]=N;ro=j;}else{right[i][j]=i==0?ro-1:min(right[i-1][j],ro-1);}}for(int j=0; j<M; j++)ans=max(ans,up[i][j]*(right[i][j]-left[i][j]+1));}printf("%d\n",ans*3);}
}
  相关解决方案