您的位置:首页 > 其它

2019牛客暑期多校训练营(第二场场)_H题Second Large Rectangle

2019-08-07 03:23 375 查看

题目链接: https://ac.nowcoder.com/acm/contest/882/H

思路:(转载自: https://www.cnblogs.com/pisceskkk/p/11229105.html)
首先考虑求最大矩形:

不妨考虑以第i行为底边的矩形,那么就转化成直方图求最大矩形面积。

如图

当我们遇到第三列时,第二列的高度已经不能拓展,因此将其清算掉,同时将第三列高度加入栈中。

即使用单调栈维护所有高度中最靠右且小于当前高度的位置(注意单调)。

进而考虑求第二大,情况有二,所有完整的尽量大的矩形中第二大,或者尽量大的矩形去掉一行或者一列。由于我们按行以此求解,只需要额外考虑去掉一列的情况就OK。

单调栈的一道经典题

力扣: 柱状图中最大的矩形: https://leetcode-cn.com/problems/largest-rectangle-in-histogram/
同样也是用单调栈去维护一个非递减序列

代码

#include <bits/stdc++.h>
using namespace std;
int mp[1005][1005];
int sum[1005];
int main()
{
ios::sync_with_stdio(false);
int n, m;
while(cin >> n >> m){
int maxn = 0, minn = 0;
string s;
for(int i = 1; i <= n; i++){
cin >> s;
sum[i] = 0;
for(int j = 1; j <= m; j++){
mp[i][j] = (s[j - 1] - '0');
}
mp[i][m + 1] = 0;
}

for(int i = 1; i <= n; i++){
stack<int> st;
int ans;
st.push(0); // 设置矩形的坐界限
for(int j =  1; j <= m + 1; j++){
sum[j] = (mp[i][j] == 1 ? sum[j] + 1 : 0);
while(st.size() > 1 && sum[j] <= sum[st.top()]){
int k = st.top();
st.pop();
ans = sum[k] * ((j - 1) - st.top());  // 宽 * 底面长
if(ans > maxn){
minn = maxn;
maxn = ans;
ans -= sum[k]; 		//因为我们求的第二大 所以我们要尝试去掉一行或者一列再去与第二大做比较, 因为我们是按行来求解的所以我们只要尝试去掉一列即可, 即宽 * (底面长 - 1)
if(ans > minn){
minn = ans;
}
}
else if(ans > minn){
minn = ans;
}
}
st.push(j);
}
}
cout << minn << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: