week5作业A题 最大矩形

题目:
给一个直方图,求直方图中的最大矩形的面积。例如,下面这个图片中直方图的高度从左到右分别是2, 1, 4, 5, 1, 3, 3, 他们的宽都是1,其中最大的矩形是阴影部分。
在这里插入图片描述
输入:
输入包含多组数据。每组数据用一个整数n来表示直方图中小矩形的个数,你可以假定1 <= n <= 100000. 然后接下来n个整数h1, …, hn, 满足 0 <= hi <= 1000000000. 这些数字表示直方图中从左到右每个小矩形的高度,每个小矩形的宽度为1。 测试数据以0结尾。
输出:
对于每组测试数据输出一行一个整数表示答案。
样例输入:
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0
样例输出:
8
4000

本题用单调栈解决。
遇到栈顶元素小于当前元素,或者栈为空时将元素压入栈。
遇到栈顶元素大于当前元素时,把栈顶元素弹出,然后根据弹出元素的高度及其元素序号来更新最大面积;继续判断,直到栈顶元素小于当前元素。
压入栈的都是元素的序号,这样可以通过当前元素的序号i,弹出元素的序号left,弹出元素的高度nowheight,得到新的面积nowheight×(i-left-1)。
此外,虽然单个数据都在int的数据范围内,但是最后的面积会超过int的范围,所以用long long类型的数据。
以下是完整代码:

#include<iostream>
#include<stack>
using namespace std;

long long height[200000];
long long max(long long x,long long y)
{
 if(x>y)
 {
  return x;
 }
 else
 {
  return y;
 }
}
void solve(int n)
{
 long long ans=0;
 long long nowHeight;
 stack<long long> s;
 for(int i=0;i<=n;i++) 
 {
  while(!s.empty()&&height[s.top()]>height[i])//当前元素小于栈顶元素 
  {
   nowHeight=height[s.top()];
   s.pop();
   int left;
   if(s.empty())
   {
    left=-1;
   }
   else
   {
    left=s.top();
   }
   ans=max(ans,nowHeight*(i-left-1));//更新面积 ans 
  }
  s.push(i); 
 }
  cout<<ans<<'\n';
}
int main()
{
 int n;
 while(1)
 {
  cin>>n;
  if(n==0)
  {
   break;
  }
  for(int i=0;i<200000;i++)
  {
   height[i]=0;
  }
  for(int i=0;i<n;i++)
  {
   cin>>height[i];
  }
  solve(n);
 }
}
发布了24 篇原创文章 · 获赞 5 · 访问量 274

猜你喜欢

转载自blog.csdn.net/qq_45639151/article/details/105006854