直方图中最大的矩形

霸气de小男生 提交于 2020-02-29 01:32:42

题目:
直方图是由在公共基线处对齐的一系列矩形组成的多边形。

矩形具有相等的宽度,但可以具有不同的高度
链接
图不知道怎么弄
例如,图例左侧显示了由高度为2,1,4,5,1,3,3的矩形组成的直方图,矩形的宽度都为1:
通常,直方图用于表示离散分布,例如,文本中字符的频率。
现在,请你计算在公共基线处对齐的直方图中最大矩形的面积。
图例右图显示了所描绘直方图的最大对齐矩形。
输入格式
输入包含几个测试用例。
每个测试用例占据一行,用以描述一个直方图,并以整数n开始,表示组成直方图的矩形数目。
然后跟随n个整数h1,…,hn。
这些数字以从左到右的顺序表示直方图的各个矩形的高度。
每个矩形的宽度为1。
同行数字用空格隔开。
当输入用例为n=0时,结束输入,且该用例不用考虑。
输出格式
对于每一个测试用例,输出一个整数,代表指定直方图中最大矩形的区域面积。
每个数据占一行。
请注意,此矩形必须在公共基线处对齐。
数据范围
1≤n≤100000,
0≤hi≤1000000000
输入:
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0
输出:
8
4000

分析,可取一个长方形条,然后该长方形条的左右两边高度大于等于它的即可把该矩形面积扩大,故转换为求该长方形条左右两边第一个比它小的长方形条位置;即为单调栈;这里运用两个单调栈,有很多写法,我的写法如下:
c++代码如下;

#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const double eps = 1e-5;
const int mod = 999911659;
const int N = 100009;
typedef pair<int,int> pii;
stack<int> sal,sar;
int a[N],bl[N],br[N];
int main(){

	int n;
	while(cin>>n&&n)
	{
		memset(bl,0,sizeof bl);
		memset(br,0,sizeof br);
		while(sar.size()) sar.pop();
		while(sal.size()) sal.pop();
		for(int i=1;i<=n;i++)
		{
			cin>>a[i];//求右边
			while(sar.size() && a[sar.top()] >= a[i])
			{
				br[sar.top()]=i;
				sar.pop();
			}
			sar.push(i);
			//求左边
			while(sal.size() && a[sal.top()] >= a[i]) sal.pop();
			if(sal.size() && a[sal.top()] < a[i]) bl[i]=sal.top();
			sal.push(i);
		}
//		for(int i=1;i<=n;i++) cout<<bl[i]<<" ";cout<<endl;
//		for(int i=1;i<=n;i++) cout<<br[i]<<" ";cout<<endl;
		ll ma=0,sum=0;
		for(int i=1;i<=n;i++)
		{
			if(br[i]==0) br[i]=n+1;//右边为0即它没有比它还小的
			sum=a[i]*(br[i]-bl[i]-1ll);//这里要转换成ll型
			ma=max(sum,ma);
		}
		cout<<ma<<endl;
	}
	return 0;
}

有问题还请联系,谢谢

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!