最大的矩形 (201312-3)

116 篇文章 2 订阅
35 篇文章 0 订阅

问题描述
  在横轴上放了n个相邻的矩形,每个矩形的宽度是1,而第i(1 ≤ i ≤ n)个矩形的高度是h i。这n个矩形构成了一个直方图。例如,下图中六个矩形的高度就分别是3, 1, 6, 5, 2, 3。



  请找出能放在给定直方图里面积最大的矩形,它的边要与坐标轴平行。对于上面给出的例子,最大矩形如下图所示的阴影部分,面积是10。
输入格式
  第一行包含一个整数n,即矩形的数量(1 ≤ n ≤ 1000)。
  第二行包含n 个整数h 1, h 2, … , h n,相邻的数之间由空格分隔。(1 ≤ h i ≤ 10000)。h i是第i个矩形的高度。
输出格式
  输出一行,包含一个整数,即给定直方图内的最大矩形的面积。
样例输入
6
3 1 6 5 2 3
样例输出
10

思路:做这道题的原因是,我同学去科大参加 华为2016年实习生笔试,这道题恰好是第2题,算简单题了。好可惜,为啥子我没去报名,不然就过了一轮笔试了。

这道题求的是最大的矩形面积,每个小方块的面积都是1。假设现在前面有了n列的矩阵,当我在放第n+1列时,最大值只可能在以下几种情况中选择:

1.第n+1列的面积最大

2.之前的最大值也是加了这一列的最大值

3.第三种情况稍复杂一点,就是用一个高度为line的直线去切割,当line=1时,看一下line以下方格的最大值,注意这里遇到h[j]<line时停止,就比如,在图例中,当添加了第4列之后,当我用line=1去切,切了四路,最大值为4。用line=2去切,只能切两路,最大值为4。当循环到line=5时,切两路最大值为10,这是当前最大值

这道题我觉得应该算动态规划的例子。用f(i) 表示前i列的最大值,则f(i+1) = max( f(i), h[i+1], max temp(1<=line<=h[i+1]))


#include <iostream>
using namespace std;

#define MAX 1010

int main(){
    int n,i,j,ans = 0;
    cin>>n;
    int h[MAX];
    for(i=0;i<n;i++){
        cin>>h[i];
    }
    int line = 0;    //line是划线,平行于x轴的线
    for(i=0;i<n;i++){
       if(i == 0)
           ans = h[0];
       else{
           ans = max(ans,h[i]);  //先和自身高度求一个最值
           line = 1;
           while(line<=h[i]){
               int num = 0;     //表示以当前高度的line可以覆盖几路
               for(j=i;j>=0;j--){
                   if(h[j]>=line)
                       num++;
                   else
                       break;
               }
               int temp = num * line;
               ans = max(ans,temp);
               line++;
           }
       }
    }
    cout<<ans<<endl;
    return 0;
}

后来在思考的过程中,又想到一种方法。从第一列开始遍历,当固定i=0时,依次加入后面的列,组成的临时矩形高度是这几列最小的高度。遍历完一遍之后,记录i=0时的最值,之后再求出i=1,2,……(n-1)时的最值,比较求出最大值就OK


#include <iostream>
using namespace std;

#define MAX 1010

int main(){
    int n,i,j,ans = 0;
    cin>>n;
    int h[MAX];
    for(i=0;i<n;i++){
        cin>>h[i];
    }
    for(i=0;i<n;i++){
        int temp;
        int low = h[i];
        for(j=i;j<n;j++){
            if(h[j]<low)
                low = h[j];
            temp = low * (j-i+1);
            if(temp > ans)
                ans = temp;
        }
    }
    cout<<ans<<endl;
    return 0;
}



vue、konva标注多边形和矩形是指在vue框架下使用konva库实现对多边形和矩形进行标注的一种解决方案。 在demo2.0中,我们可以首先使用vue-cli创建一个新的vue项目,并安装konva库。接下来,在项目中引入konva库,并创建一个konva舞台(Stage)和一个konva层(Layer),用于显示多边形和矩形。 对于多边形标注,我们可以监听用户的鼠标点击事件,并使用konva的Line组件来绘制多边形。当用户点击时,我们可以记录下鼠标的坐标,并将其添加到多边形的坐标数组中。同时,我们还可以在每次点击后重新绘制多边形,显示出用户已经绘制的线段。 对于矩形标注,我们可以监听用户的鼠标按下和抬起事件,并分别记录下按下和抬起时的鼠标坐标。在按下和抬起时,我们可以使用konva的Rect组件来绘制矩形,并根据按下和抬起的坐标计算出矩形的宽度和高度。 除了标注绘制外,我们还可以对绘制的多边形和矩形进行编辑和删除。例如,我们可以监听用户的鼠标双击事件,并根据鼠标的位置找到用户点击的多边形或矩形。然后,我们可以在选中的多边形或矩形上显示编辑手柄,并监听手柄的拖拽事件,实现对多边形或矩形的位置、大小的编辑。同时,我们可以提供一个删除按钮,用户点击后可以将选中的多边形或矩形删除。 总之,vue、konva标注多边形和矩形的demo2.0提供了一个方便实用的工具,可用于在图形界面上进行多边形和矩形的标注,并具备编辑和删除功能。通过这种方式,用户可以更加直观地进行图形标注和处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值