最大子方块
题目如下:
分析:
建立一个二维数组,每个点有三个变量,长,高,面积;
数组为1时,长,高,面积为1;
数组为0时,长,高,面积为0;
然后从左上角开始遍历数组,当左边的点非0时,把左边的点的长加1:p[i][j].l=p[i][j-1].l+1;
同理:当上面的点非0时,把上面的点的高加1:p[i][j].h=p[i-1][j].h+1;
赋值好了后开始递归计算最大空间:
最大子方块有如下三种情况:1.上面和左边都是0时;面积为1;
2. 上面或则下面有一个不为0时,面积为p[i][j]中l和h的最大值。
3. 上面和下面都不为0时,面积按照下图计算:
我们一次次比较黑紫绿黄蓝红这五个长方形面积 得出做大面积,将其赋值给面积。
#include<iostream>
#include<string>
using namespace std;
//我们所要使用的结构体;
struct point
{
int l,h,are;//长,高,面积;
//初始化
void set()
{
l=h=are=0;
}
void out()
{
if(are>=10)
cout<<"("<<l<<"*"<<h<<"="<<are<<") ";
else
cout<<"("<<l<<"*"<<h<<"="<<are<<" ) ";
}
};
int main()
{
int n,m,i,j;
int ad[30][30];
point p[30][30];
string s;
while(cin>>n>>m)
{
//初始化将数组清零;
for(i=0;i<=n;i++)
for(j=0;j<=m;j++)
p[i][j].set();
//输入字符串,将其赋值,数组从下标1,1开始
for(i=1;i<=n;i++)
{
cin>>s;
for(j=0;j<m;j++)
p[i][j+1].h=p[i][j+1].l=p[i][j+1].are=s[j]-'0';
}
//计算最大子空间
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
//当p[i,j]不为零时,分析:
if(p[i][j].l!=0&&p[i][j].h!=0)
{
//遍历数组,设置数值给l,h;
if(p[i-1][j].h!=0)
p[i][j].h=p[i-1][j].h+1;
if(p[i][j-1].l!=0)
p[i][j].l=p[i][j-1].l+1;
//处于情况1,2;上面和下面至少有一个不为零时,取p[i][j]的l和h的最大值赋值给are
if(p[i-1][j].h==0||p[i][j-1].l==0)
{
if(p[i][j].h>p[i][j].l)
p[i][j].are=p[i][j].h;
else
p[i][j].are=p[i][j].l;
}
else//处于情况3;上面和下面全不为零时,取计算所得的面积最大值赋值给are
{
int min;
min=p[i][j].h;
//向左递归,计算矩形面积。用min记录最小的高
for(int k=j;p[i][k].l!=0;k--)
{
//向左递归,发现比min更小的高时,刷新min的值;
if(min>p[i][k].h)
min=p[i][k].h;
//此时面积=min*宽;若比are更大,刷新are的值;
if(min*(j-k+1)>=p[i][j].are)
p[i][j].are=min*(j-k+1);
}
}
}
}
}
/* 解除屏蔽后,可以看到求得的数值
for(i=0;i<=n;i++)
{
for(j=0;j<=m;j++)
p[i][j].out();
cout<<endl;
}
cout<<endl;
*/
//设置一个max,循环数组的最大子面积
int max=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(p[i][j].are>max)
max=p[i][j].are;
}
}
cout<<max<<endl;
}
return 0;
}