SMU_problem1357最大子方块

最大子方块

题目如下:

分析:

建立一个二维数组,每个点有三个变量,长,高,面积;

数组为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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值