51nod 1102 面积最大的矩形 新疆大学OJ 1387: B.HUAWEI's billboard 【单调栈】+【拼凑段】(o(n) 或 o(nlog(n))
题面1:

题面2:

两道题除了数据范围不同,没有任何差异,两道题都可以o(n)(单调栈),o(nlog(n))(我自己的做法)解决。
解题思路1:(单调栈)
- 对于每个点找到右边第一个比它小的位置con1,并且找到左边第一个比它小的位置con2。
- 对于每个点更新答案为ans = max(ans, (con2-con1-1)*value[i])。
- 1的做法是两次裸的单调栈,时间复杂度为o(n)。
代码1:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//在新疆大学OJ提交需要将此处三个数组改为500010,否则会运行超时
ll a[50010];
int l[50010],r[50010];
int main(){ios::sync_with_stdio(false);int n;cin >> n;ll ans = 0;for(int i = 1;i <= n; ++i){cin >> a[i];}a[0] = a[n+1] = -1;stack<int> s;s.push(1);for(int i = 2;i <= n+1; ++i){if(a[i] < a[s.top()]){while(s.size() and a[i] < a[s.top()]){r[s.top()] = i;s.pop();}}s.push(i);}while(s.size()) s.pop();s.push(n);for(int i = n-1;i >= 0; --i){if(a[i] < a[s.top()]){while(s.size() and a[i] < a[s.top()]){l[s.top()] = i;s.pop();}}s.push(i);}for(int i = 1;i <= n; ++i){ans = max(ans, (a[i]*(r[i]-l[i]-1)));}cout << ans << endl;return 0;
}
解题思路2:(拼凑段)
- 这是我自己瞎搞的写法,不知道算什么方法,不过大家可以看一看思路,可能什么时候就能用到了。
- 首先,记下输入的数字的位置,然后对这个结构体按数字从打到小排序。
遍历这个结构体数组(这时数字是从大到下的),段(一个结构体,有l,r,used三个成员变量,l指这个段的左端位置,r指这个段的右端位置)
a. 若这个数字的原位置的左右边两个数字都已形成段,则将这两段拼成一段,具体做法是将左边段的r延长至右端,当前数字为这一段的最小值,更新ans。
b. 若这个数字的原位置的左边形成段,右边没有形成段,则把这个数字加入到左边的段,当前数字为这一段的最小值,更新ans。
c. 若这个数字的原位置的右边形成段,左边没有形成段,则把这个数字加入到右边的段,当前位置为这一段的最小值,更新ans。
d. 若这个数字的原位置的左边和右边都没有形成段,则把这个数字加入到一个新的段,新的段的l和r都等于这个数字的原先位置,更新ans。可能会想到查找左边位置所处的段和右边所处的段需要o(n)处理起来会变成o(n^2),这时候我们加一个索引数组index,index[i]表示位置为i的数字所处的段。
- 可能还会想到更新index需要花费o(n),处理起来会变成o(n^2),但是仔细想想我们会发现不需要更新这个段所有的index,只用更新index[l]和index[r],因为中间的在后面将不会用到。
- 这样算下来排序的时间复杂度是o(nlogn),处理的时间是o(n),总时间复杂度就是o(nlogn)。
- 可能还有人问为什么正确?排序之后先插入大的,后插入小的,会发现当前插入的这个点一定是这个点的最优情况。
代码2:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//在新疆大学OJ提交需要将此处的50010全部改为500010 //输入的数组,val为这个点的数字,idx表示原下标。
struct node{ll val;int idx;
}a[50010];
//段,l表示左端,r表示右端 ,k表示段的个数。
struct segment{int l;int r;
}seg[50010];
int k = 1;
//index[i]表示第i个位置数字所处的段。
int index[50010];int n;
bool cmp(node x,node y){return x.val > y.val;
}int main(){ios::sync_with_stdio(false);int n;cin >> n;ll ans = 0;for(int i = 1;i <= n; ++i){cin >> a[i].val;a[i].idx = i;ans = max(ans , a[i].val);}sort(a+1, a+1+n, cmp);for(int i = 1;i <= n; ++i){int idxl = index[a[i].idx-1];int idxr = index[a[i].idx+1];if(idxl != 0 and idxr != 0){ //左右边都形成一段。 seg[idxl].r = seg[idxr].r;index[seg[idxr].r] = idxl;ans = max(ans, a[i].val*(seg[idxl].r-seg[idxl].l+1));}else if(idxl != 0 and idxr == 0){ //左边形成段,右边未形成。 seg[idxl].r++;index[a[i].idx] = idxl;ans = max(ans, a[i].val*(seg[idxl].r-seg[idxl].l+1));}else if(idxl == 0 and idxr != 0){ //右边形成段,左边未形成。 seg[idxr].l--;index[a[i].idx] = idxr;ans = max(ans, a[i].val*(seg[idxr].r-seg[idxr].l+1));}else if(idxl == 0 and idxr == 0){ //左右边均未形成段。 seg[k].l = a[i].idx;seg[k].r = a[i].idx;index[a[i].idx] = k; k++;}}cout << ans << endl;return 0;
}
51nod 1102 面积最大的矩形 新疆大学OJ 1387: B.HUAWEI's billboard 【单调栈】+【拼凑段】(o(n) 或 o(nlog(n))相关推荐
- 51Nod 1102 面积最大的矩形 +1272 最大距离 单调栈
51Nod 1102 面积最大的矩形 记笔记记笔记:对于区间最值与区间长度/和等的问题,用单调栈来维护区间端点. 这里来补一补单调栈和单调队列的基础知识: 单调栈: ...
- leetcode84- 柱状图中最大的矩形(三种思路:暴力,单调栈+哨兵(详解),分治)
leetcode84- 柱状图中最大的矩形(三种思路:暴力,单调栈+哨兵(详解),分治) 介绍 题目 解题思路 解法一:暴力向两边搜索 解法二:单调栈 画图演示 宽度计算: 解法三:单调栈+哨兵 解法 ...
- SUST OJ 1675: Fehead的项目(单调栈)
1675: Fehead的项目 时间限制: 1 Sec 内存限制: 128 MB 提交: 41 解决: 27 [提交][状态][讨论版] 题目描述 Fehead俱乐部接手了一个项目,为了统计数据, ...
- 51nod 1158 全是1的最大子矩阵(单调栈 ,o(n*m))
前置问题:51nod 1102 面积最大的矩形 附上链接: 51nod 1102 面积最大的矩形 这题的题解博客 需要了解的知识:单调栈,在前置问题中已经讲解. 解题思路 对每行求左边连续1的个数,得 ...
- 的input最大长度_LeetCode 84 | 单调栈解决最大矩形问题
今天是LeetCode专题第52篇文章,我们一起来看LeetCode第84题,Largest Rectangle in Histogram(最大矩形面积). 这道题的官方难度是Hard,点赞3581, ...
- 如何用课件制作工具演示面积一定的矩形
作为数学老师必备的课件制作工具,几何画板不仅可以画固定形状的几何图形,还可以构造变换的几何图形.比如可以用它来演示面积一定的矩形,那就说明矩形的长和宽是可以变化的,可以看到矩形的形状是变化的.下面就一 ...
- 计算直方图中面积最大的矩形
CSDN编程挑战里的题目 给定直方图,每一小块的height由N个非负整数所确定,每一小块的width都为1,请找 出直方图中面积最大的矩形. 如下图所示,直方图中每一块的宽度都是1,每一块给定的高度 ...
- 【每日一题】最大正方形面积——进阶,矩形面积
2020/05/08 每日一题 221 最大正方形面积 是一道做过的题目出现在了每日一题,今后的每日一题我尽量把相关的题目都写一遍. 这道题目的思路并不是看到01矩阵就采用暴力的bfs方法,而是可以采 ...
- POJ 2559 题解 最大矩形面积 单调栈
[题目描述]: 地面上从左到右并排紧挨着摆放多个矩形,已知这此矩形的底边宽度都为1,高度不完全相等.求在这些矩形包括的范围内能得到的面积最大的矩形,打印出该面积.所求矩形可以横跨多个矩形,但不能超出原 ...
最新文章
- 2.2 物理层传输介质
- 数据集神经网络共同进步
- 射线法 java_射线法(1190 - Sleepwalking )
- java web从入门到精通视频_JavaWeb从入门到精通(视频实战版)
- 2020 年 Service Mesh 技术展望
- gym 102875 H. Happy Morse Code
- TomCat使用以及端口号被占用的处理方法
- opencv计算物体姿态旋转_物体的三维识别与6D位姿估计:PPF系列论文介绍(五)...
- 20个软件开发常用设计文档大全下载
- 计算机考研调剂规则,21考研调剂规则大变化,这类学生不能调剂!
- 用8张图理解Java
- N76E003的学习之路(一)
- Python的继承与多继承
- 深入理解和使用nginx
- 计算机操作系统第四版课后习题答案(完整版)
- AD快捷键备份20210202
- EDA技术及应用实验2 h_adder程序
- 联想g510升级换什么cpu好_联想G510笔记本完全拆机指南(图解)
- php1蛋白质带电情况,拿到一个蛋白以后,首先需要对蛋白进行全面的了解,所谓知彼知己方能百战不殆:...
- 网络信息安全期末复习要点
热门文章
- Java黑皮书课后题第7章:*7.22(计算一个字符串中大写字母的数目)编写程序,从命令行输入一个字符串,然后显示字符串中大写字母的数目
- whiel oracle,Oracle中的for和while循环
- java理念_java温故而知新(9)OOP(面向对象编程)理念
- 15个Google面试题以及答案~~~~你会几个?
- 任意长度的高精度大整数加法
- mongoose 验证
- P4198 楼房重建
- $.ajax()方法详解(网上引用)
- halcon11用于C++的HTuple.h头文件,纯手添中文翻译!
- HNCU 1741: 算法3-2:行编辑程序