最后一道题,刚好做完了,但对于这道题,我一定要提上来讲解一下它,这道题来来回回用了3~4种不同的方法花式T题,最后A的那一瞬间悲喜交加!
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.
InputThe first line of the input 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:
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.
R – reserved unit
F – free unit
In the end of each area description there is a separating line.
OutputFor each data set in the input 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 RSample Output
45 0
我看过无数的人说这道题与之前的这一道题是相同的,但我觉得也相同也不同,这样子的一道题让我感触还是挺深的。
思路:它让我们求的是折服图中由'F'构成的矩形的面积最大值*3的值,我想到的第一个方法,也就是最接近answer的一个方法就是把每个点的值从左往右排,遇到'R'就清零然后在继续累加,毫无疑问,这样的思路跟前面做的这道题方法是相同的,我们之后只要一一遍历它的左右极限即可,但是T了2发之后就发现没那么简单。
改进后的正解:想了个办法优化,既然从左往右这样叠出来的矩阵方法不可以,那么不如从上往下用这样的方法进行操作,然而这样的方法会比之前从左往右简单,因为这个方法是套在for循环之中的,就可以减少一层循环做到优化,我们每一排开始输入,然后就直接进行操作,假如输入的是'F',那么对于这一列,我们列长就增加了,同理,遇到'R',那么这就是个断点了,我们执行清零处理,然后从新排长度,与此同时,我们对于每一个j列进行找到它的左右极端并直接求面积与ans比较,这样可以省出时间与空间。求左右极端的方法与这道题目相同。
完整代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,m;
int h[1005]; //用来记录横排此处的位置的高度
int l[1005];
int r[1005]; //左右分别能到达的最远距离
int main()
{
int T;
scanf("%d",&T);
// int Case=0;
while(T--)
{
// Case++;
// if(Case>1)cout<<endl;
int ans=0;
scanf("%d%d",&n,&m);
memset(l, 0, sizeof(l));
memset(r, 0, sizeof(r));
memset(h, 0, sizeof(h));
h[0]=h[m+1]=-1;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
char temp[5];
scanf("%s",temp);
if(temp[0]=='F') //若'F',高加一
{
h[j]++;
}
else
{
h[j]=0;
}
l[j]=j;
while(h[l[j]-1]>=h[j])
{
l[j]=l[l[j]-1];
}
}
for(int j=m; j>=1; j--)
{
r[j]=j;
while(h[r[j]+1]>=h[j])
{
r[j]=r[r[j]+1];
}
}
for(int j=1; j<=m; j++)
{
int s=h[j]*(r[j]-l[j]+1);
if(s>ans)
{
ans=s;
}
}
}
printf("%d\n",ans*3);
}
return 0;
}