题意介绍
给一个直方图,求直方图中的最大矩形的面积。
题意分析
下面这个图片中直方图的高度从左到右分别是2, 1, 4, 5, 1, 3, 3, 他们的宽都是1,其中最大的矩形是阴影部分。
本题考察单调栈,以上面的例子为例来说明单调栈的工作过程,首先将第一个矩形压入栈(实际是把该矩形的高度在数组中的索引值压入栈),然后继续向右遍历,以找到由栈内矩形能形成的最大矩形,第二个矩形的高度为1,小于栈内矩形,该矩形不能入栈,说明栈内矩形的最右边界已经找到,将其弹出栈,并计算矩形面积。将第二个矩形压入栈,但三个矩形可以压入栈,第四个不行,找到右边界,依次弹出第三个矩形和第二个矩形,每次弹出计算左边界和右边界之间的矩形的面积。当将所有的矩形都遍历完后,如果栈不空,以n(矩形个数)为右边界,依次弹出矩形,找到左边界,计算面积。
通过代码
#include<iostream>
#include<stack>
#include<algorithm>
using namespace std;
int n;
long long arr[100000];
long long mx = 0;
int main() {
ios::sync_with_stdio(false);
cin >> n;
while ( n != 0) {
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
stack<int> s;
for (int i = 0; i < n; i++) {
while (!s.empty() && arr[s.top()] >= arr[i]) {
int cur = s.top();
s.pop();
int left = (s.empty()) ? -1 : s.top();
long long area = (i-left - 1)*arr[cur];
mx = max(mx, area);
}
s.push(i);
}
while (!s.empty()) {
int cur = s.top();
s.pop();
int left = (s.empty()) ? -1 : s.top();
long long area = (n- left - 1)*arr[cur];
mx = max(mx, area);
}
cout << mx << endl;
mx = 0;
cin >> n;
}
return 0;
}