标签:CSP201312 遍历 最大 int 元素 栈顶 st maxn 矩形
CSP201312-3 最大矩形
题目要求:
找出给定直方图中面积最大的矩形。
解题思路
利用单调栈的思想。对于输入的高度数组,向右和向左两次遍历扫描,对于当前考虑的元素h[i]来说,分别找到向右的第一个小于h[i]的元素的下标和向左的第一个小于h[i]的元素的下标。两者只差就是可以以h[i]作为矩形高的矩形的长。
这里使用数组来模拟栈。当前考虑的元素为栈顶元素。栈内保存的是元素的下标。利用栈顶元素和循环遍历的元素相比较。值的注意的是,为了能够最后将栈中所有元素都弹出,在向右遍历的时候需要比输入的高度数组h的元素个数n多1,且h[n+1]=0。同理在向左遍历的时候,需要用到h[0]=0。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int n;
const int maxn = 1e3 + 5;
// R,L中分别存放的是向右和向左的第一个小于自己的元素的下标值,st数组模拟栈
int h[maxn],R[maxn],L[maxn],st[maxn];
int main(void) {
scanf("%d", &n);
int i;
for (i = 1; i <= n; i++)
scanf("%d", &h[i]);
int r=1;//r是栈顶指针
st[r]=1;//栈里面存放的是元素的下标值
// 1. 向右遍历找到第一个小于自己的元素
for (i = 1; i<=n+1; i++) {
while (r>0&&h[st[r]] > h[i]) {
//如果栈顶元素大于当前考虑的元素
R[st[r]] = i-1;
r--;//使用while循环是为了维护的单调性
}
//如果栈顶元素小于等于当前考虑的元素直接入栈
st[++r] = i;
}
//向左遍历找到第一个小于自己的元素
memset(st, 0, sizeof(st));//先清空
r = 1;
st[r] = n;
for (i = n - 1; i>=0; i--) {
while (r > 0 && h[st[r]] > h[i]) {
//如果栈顶元素大于当前考虑的元素
L[st[r]] = i+1;
r--;//使用while循环是为了维护的单调性
}
//如果栈顶元素小于等于当前考虑的元素直接入栈
st[++r] = i;
}
int ans = 0;
for (i = 1; i <= n; i++)
ans = max(ans, (R[i] - L[i] + 1) * h[i]);
printf("%d", ans);
return 0;
}
标签:CSP201312,遍历,最大,int,元素,栈顶,st,maxn,矩形 来源: https://blog.csdn.net/qq_43725311/article/details/115468700
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。