http://acm.hdu.edu.cn/showproblem.php?pid=1505
题意:题目要求我们在给出的一个n*m的矩阵里面积求出他的最大可利用的面积。就是算出可以组成多大的面积(最大),最大的面积中间不可以有被占领的土地。
次题类似与1506题,只是其中要有点变化,就是怎么把其中的“F”(空地),变成我们所需要用的高度呢?而且棘手的是这题还是二维的,这样就加大了难度,因此有必要定义一个二维的h[][],来储存高度的。这样接下来就是怎样处理这个高度问题了。首要思路就是到底将行变还是列变,这里就用就将每组的“F”,即每个位置以上的"F“个数。(上一个是”F“)。依次这样就把所有的个数求出来了。。接下来就是根据1506题的做法来解决了!!
一些注意见代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=1005;
//char map[maxn];
char a[maxn][maxn];
int h[maxn][maxn],l[maxn],r[maxn];
int n,m;
/*void f()
{
int i;
for(i=0;i<m;i++)
{
r[i]=i;
l[i]=i;
}
}*/
void get_h()
{
int i,j;
memset(h,0,sizeof(h));
for(i=0;i<m;i++)
{
h[0][i]=0;//初始化。
}
for(i=1;i<=n;i++)
{
for(j=0;j<m;j++)
{
if(a[i][j]=='F')
{
h[i][j]=h[i-1][j]+1;//计算出每个位置以上以及本身的个数(F)。这样就化为高度的处理的方式。
}
else
h[i][j]=0;
}
}
}
int get_are()
{
int i,j;
f();
get_h();
int ans=0,k;
for(i=1;i<=n;i++)
{
memset(l,0,sizeof(l));
memset(r,0,sizeof(r));
for(j=0;j<m;j++)
{
l[j]=j;//这里必须这样处理,因为如果放到一个函数里处理的话就可能超时。同下。。
while(h[i][l[j]-1]>=h[i][j]&&l[j]>0)
//h[i][j]=h[i][l[j]-1];
l[j]=l[l[j]-1];
}
for(j=m-1;j>=0;j--)
{
r[j]=j;//
while(h[i][r[j]+1]>=h[i][j]&&r[j]<m-1)
{
// h[i][j]=h[i][r[j]-1];
r[j]=r[r[j]+1];
}
}
for(j=0;j<m;j++)
{
k=(r[j]-l[j]+1)*h[i][j];
if(ans<k)
ans=k;
}
}
return ans;
}
int main()
{
int i,j,t,sum;
char map[10];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
for(j=0;j<m;j++)
{
scanf("%s",&map);//这样处理可以解决的空格,换行的问题,都可以不管。
a[i][j]=map[0];//再将所值赋给a[i][j]。
}
}
sum=get_are();
printf("%d\n",sum*3);
/* if(t!=0)
printf("\n\n");*/
}
return 0;
}