201312-3 CCF试题简析

1.试题描述
在横轴上放了n个相邻的矩形,每个矩形的宽度为1,而第i(1<<i<<n)个矩形的高度为Hi。这n个矩形构成了一个直方图。例如,下图中六个矩形的高度就分别是3,1,6,5,2,3。在这里插入图片描述
请找出能放在给定直方图里面积最大的矩形,它的边要与坐标轴平行。对于上面给出的例子。最大矩形如下图所示的阴影部分,面积是10.

在这里插入图片描述

输入格式:
  • 第一行包含一个整数n,即矩形的数量(1<=n<=1000)。
  • 第二行包含n个整数h1,h2,…,hn,即相邻的数之间由空格分隔。(1<=hi<=10000)hi为第i个矩形的高度
输出格式:
  • 输出一行,包含一个整数,即给定直方图内的最大矩形的面积。
样例输入:
  • 6
  • 3 1 6 5 2 3
样例输出:
  • 10

2.问题分析与实现代码
第一种方法是使用暴力破解,算法复杂度O(n*n) 。先设第一个数为最小值h,然后依次查找矩形比这个数小的,找到最小,计算面积,求出最大值,如此规律计算出所有可能出现的矩形面积结果,最后求出最大值。

#include<iostream>
int main()
{
 int n,i,j,h,s,max,a[1001];
 cin>>n;
 for(i=0;i<n;i++)
 cin>>a[i];
 max=0;
 //从第一个矩形开始,往右扫描,
 //若后面的矩形高度比第一个低,
 //则h为较低的那个值,不断发生改变 
 for(i=0;i<n;i++)
 {
  h=a[i]; 
  for(j=i;j<n;j++)
  {
     if(a[j]<h) 
      h=a[j];
      s=h*(j-i+1);   //矩形面积=长X宽 
      if(s>max)
      max=s;
  } 
 }

第二种方法主要使用栈,时间复杂度O(n)。先找到一个逐步递增的面积,即如果Hi<Hi+1,则最大面积是逐步递增的。这个过程中,将这些Hi放入堆栈中,知道不满足Hi<Hi+1,则最大面积是逐渐递增的。这个过程中,将这些Hi放入堆栈中,知道不满足Hi<Hi+1为止。这个时候,最大的面积可能是最右边Hi,由若干块拼成,从中获得一个最大的面积。出现面积非递增式,则把堆栈中比当前高的直方图弹出,重复上述过程。

#include "iostream"
#include "stack"
#include "vector"
#include "algorithm"
// 
using namespace std;
 
int getMaxArea(vector<int> &hist)
{
	
    stack<int> s;
 
    int i;
    int max=0;
    int max_area=0;
    int tp, area_with_top;
 
    while(i < hist.size())
    {
    	//若栈为空或者栈顶元素小于hist[i],就入栈 
        if(s.empty() || hist[s.top()] <= hist[i])
            s.push(i++);
        else
        {
        	//否则,就计算此时的面积,与max_area进行比较 
            tp = s.top();
            s.pop();
            area_with_top = hist[tp] * (s.empty() ? i : i-s.top()-1);
             if(max_area<area_with_top){
             	max_area=area_with_top;
			 }
        }
    }
    while(!s.empty())
    {
        tp = s.top();
        s.pop();
        area_with_top = hist[tp] * (s.empty() ? i : i-s.top()-1);
        if(max_area<area_with_top){
             	max_area=area_with_top;
			 }
    }
 
    return max_area;
}
 
int main()
{
    int N;
    vector<int> vec;
    //输入数据 
    cin >> N;
    for(int i=0;i<N;i++)
    {
        int val;
        cin >> val;
        vec.push_back(val);
    }
    //调用获得最大面积函数 
    cout << getMaxArea(vec);
}

参考:https://www.bbsmax.com/A/QW5YDNPNJm/

发布了32 篇原创文章 · 获赞 32 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/Evan_love/article/details/104987043