题解:B4273 [蓝桥杯青少年组省赛 2023] 最大的矩形纸片
superLouis · · 题解
题解:B4273 [蓝桥杯青少年组省赛 2023] 最大的矩形纸片
这题一眼就是单调栈嘛。
1. 解题思路
老规矩,我们先来算算样例:
样例输出是 8,也就是第
题目要求的就是上面这种图(下边固定)中最大矩形的面积。那我们思考一下,矩形面积是由一个底面长度乘上高所得来的。
解题的思路就是不妨固定一个高,求这个高的最长底面长度。具体一点,就是对于每一个竖列(假设高度是
再思考一下,怎样算出第一个比它靠右并且低于它高度的和第一个比它靠左并且低于它高度的?
其实这就是单调栈解决的基本问题啦,不懂的可以去看看 【模板】单调栈,这里的问题就是现在解决的问题。只是这里需要两个单调栈维护(不是求左边的和右边,一共两个方向嘛)即可了。
2. 时间复杂度
对于单调栈,也就是预处理部分,每个元素都只进出栈一次,
对于处理的部分,
最后这个思路时间复杂度
3. 代码实现
就知道你们最想要这个。。。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e6 + 10;
int n, a[maxn], l[maxn], r[maxn];
ll ans;
struct node { int idx, num; };
stack<node> lstk, rstk;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) {
while (lstk.size() && lstk.top().num > a[i]) {
l[lstk.top().idx] = i;
lstk.pop();
}
lstk.push(node({i, a[i]}));
}
for (int i = n; i >= 1; i--) {
while (rstk.size() && rstk.top().num > a[i]) {
r[rstk.top().idx] = i;
rstk.pop();
}
rstk.push(node({i, a[i]}));
}
for (int i = 1; i <= n; i++) if (l[i] == 0) l[i] = n + 1;
for (int i = 1; i <= n; i++) ans = max(ans, (ll)(l[i] - r[i] - 1) * (ll)a[i]);
cout << ans << "\n";
return 0;
}
自认为码风良好。(我是不是太自恋了???)
通过记录(不要质疑我~)