2019牛客暑期多校训练营(第二场) H-Second Large Rectangle(单调栈)
题意:给出由01组成的矩阵,求求全是1的次大子矩阵。
思路:
单调栈
全是1的最大子矩阵的变形,不能直接把所有的面积存起来然后排序取第二大的,因为次大子矩阵可能在最大子矩阵里面,比如:
| 1 | 0 | 0 |
| 1 | 1 | 1 |
| 1 | 1 | 1 |
有篇博主的代码细节处理的很好,由于矩阵每行的长度一致,则不必重复在数组末尾标记0;然后由于j是从1,最开始如果push进0的话,有两个好处:
1.可以不受栈之前“残留”的元素m+1的影响
2.不用再判断栈是某为空来确定wid的值
Code
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 7; int n, m, ans;
string str[N];
int h[N], mx1, mx2;
stack <int> s; void solve(int x)
{
if(x > mx1)
mx2 = mx1, mx1 = x;
else if(x > mx2) mx2 = x;
}
int main()
{
scanf("%d%d",&n, &m);
for(int i = 1; i <= n; i++) {
cin >> str[i];
for(int j = 1; j <= m; j++) {
if(str[i][j-1] == '1') h[j] += 1;
else h[j] = 0;
}
s.push(0);
for(int j = 1; j <= m + 1; j++) {
while(h[j] < h[s.top()]) {
int index = s.top(); s.pop();
int x = j - 1 - s.top(), y = h[index];
solve(x * y);
solve((x - 1)* y);
solve(x * (y - 1));
}
s.push(j);
}
}
cout << mx2 << endl;
}
悬线法
通过悬线法,可以找到以点(i,j)为底的极大矩形。
u[i][j]、l[i][j]、r[i][j]分别表示以为底的极大矩形的上边界,左边界,右边界;
首先预处理:找到点(i,j)可以沿伸的的上端点、左端点,右端点 (dp)
For i = 1 to n
For j = 1 to m
u[i][j] = (i-1,j)==1 ? u[i-1][j] : i;
l[i][j] = (i,j-1)==1 ? l[i][j-1] : j;
For j = m to 1
r[i][j] = (i,j+1)==1 ? r[i][j+1] : j;

如图找到了(4,3) 的 上端点、左端点,右端点,但是这些边界并没有组成一个矩形,可以(4,3)的上端点为上边界,找到左右边界,这样就可以找到一个以点(4,3)为底、以点(4,3)上界为高的极大矩形。
For i = 1 to n
For j = 1 to m
if (i-1,j)==1
l[i][j] = max(l[i][j], l[i-1][j]
r[i][j] = min(r[i][j], r[i-1][j]

#include<bits/stdc++.h>
using namespace std; const int N = 1e3+100; int n, m;
int g[N][N];
int u[N][N], l[N][N], r[N][N];
int hh, ll, rr, bb;
char str[N];
int main()
{
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++){
scanf("%s",str+1);
for(int j = 1; j <= m; j++ ){
if(str[j] == '1') g[i][j] = 1;
else g[i][j] = 0;
}
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
u[i][j] = l[i][j] = r[i][j] = 0; for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(g[i][j] == 0) continue;
u[i][j] = g[i-1][j] == 1 ? u[i-1][j] : i;
l[i][j] = g[i][j-1] == 1 ? l[i][j-1] : j;
}
for(int j = m; j >= 1; j--){
if(g[i][j] == 0) continue;
r[i][j] = g[i][j+1] == 1 ? r[i][j+1] : j;
}
}
int ans = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(g[i][j] == 0) continue;
if(g[i-1][j] == 1) {
l[i][j] = max(l[i][j], l[i-1][j]);
r[i][j] = min(r[i][j], r[i-1][j]);
}
if(ans<(r[i][j]-l[i][j]+1)*(i-u[i][j]+1)){
hh = u[i][j] , bb =i;
rr = r[i][j],ll=l[i][j];
ans = (r[i][j]-l[i][j]+1)*(i-u[i][j]+1);
}
}
}
int ans2 = max((rr-ll)*(bb-hh+1), (rr-ll +1)*(bb-hh));
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(g[i][j] == 0) continue;
if(hh==u[i][j]&&bb==i&&ll==l[i][j]&&rr==r[i][j])
continue;
if(ans2<(r[i][j]-l[i][j]+1)*(i-u[i][j]+1)){
ans2=(r[i][j]-l[i][j]+1)*(i-u[i][j]+1);
}
}
}
cout << ans2 << endl;
return 0;
}
悬线法的学习可以参考这篇博客(小声bb:虽然感觉现在没什么用,还不如单调栈)
https://blog.csdn.net/dbc_121/article/details/77503611
2019牛客暑期多校训练营(第二场) H-Second Large Rectangle(单调栈)的更多相关文章
- 牛客多校第二场H Second Large Rectangle 单调栈or悬线法
Second Large Rectangle 题意 给出n*m的01矩阵,问由1组成的第二大的矩阵的大小是多少? 分析 单调栈(or 悬线法)入门题 单调栈 预处理出每一个点的最大高度,然后单调栈每一 ...
- 2019 牛客暑期多校 第二场 H Second Large Rectangle (单调栈)
题目:https://ac.nowcoder.com/acm/contest/882/H 题意:一个大的01矩阵,然后现在要求第二大的全一矩阵是多少 思路:在这里我们首先学习一下另一个东西,怎么求直方 ...
- 2020牛客暑期多校训练营 第二场 K Keyboard Free 积分 期望 数学
LINK:Keyboard Free 我要是会正经的做法 就有鬼了. 我的数学水平没那么高. 三个同心圆 三个动点 求围成三角形面积的期望. 不会告辞. 其实可以\(n^2\)枚举角度然后算出面积 近 ...
- 2020牛客暑期多校训练营 第二场 J Just Shuffle 置换 群论
LINK:Just Shuffle 比较怂群论 因为没怎么学过 置换也是刚理解. 这道题是 已知一个置换\(A\)求一个置换P 两个置换的关键为\(P^k=A\) 且k是一个大质数. 做法是李指导教我 ...
- 2020牛客暑期多校训练营 第二场 I Interval 最大流 最小割 平面图对偶图转最短路
LINK:Interval 赛时连题目都没看. 观察n的范围不大不小 而且建图明显 考虑跑最大流最小割. 图有点稠密dinic不太行. 一个常见的trick就是对偶图转最短路. 建图有点复杂 不过建完 ...
- 2020牛客暑期多校训练营 第二场 C Cover the Tree 构造 贪心
LINK:Cover the Tree 最受挫的是这道题,以为很简单 当时什么都想不清楚. 先胡了一个树的直径乱搞的贪心 一直过不去.后来意识到这类似于最经典长链剖分优化贪心的做法 然后那个是求最大值 ...
- 2020牛客暑期多校训练营 第二场 B Boundary 计算几何 圆 已知三点求圆心
LINK:Boundary 计算几何确实是弱项 因为好多东西都不太会求 没有到很精通的地步. 做法很多,先说官方题解 其实就是枚举一个点 P 然后可以发现 再枚举一个点 然后再判断有多少个点在圆上显然 ...
- 2020牛客暑期多校训练营 第二场 A All with Pairs 字符串hash KMP
LINK:All with Pairs 那天下午打这个东西的时候状态极差 推这个东西都推了1个多小时 (比赛是中午考试的我很困 没睡觉直接开肝果然不爽 一开始看错匹配的位置了 以为是\(1-l\)和\ ...
- 2019牛客暑期多校训练营(第九场) D Knapsack Cryptosystem
题目 题意: 给你n(最大36)个数,让你从这n个数里面找出来一些数,使这些数的和等于s(题目输入),用到的数输出1,没有用到的数输出0 例如:3 4 2 3 4 输出:0 0 1 题解: 认真想一 ...
随机推荐
- 第12章 DOM操作
目录 *1. 向DOM中注入HTML 1.1 将HTNL字符串转换成DOM 预处理HTML源字符串 包装HTML 1.2 将DOM元素插入到文档中 2. DOM的特性和属性 通过DOM方法和属性访问特 ...
- Java微服务 vs Go微服务,究竟谁更强!?
前言 Java微服务能像Go微服务一样快吗? 这是我最近一直在思索地一个问题. 去年8月份的the Oracle Groundbreakers Tour 2020 LATAM大会上,Mark Nels ...
- CTFHub - Web(四)
最近又是每天忙到裂开,,,淦 xss: 反射型: 1.第一个输入框与下面Hello后的内容相同,猜测可以通过该输入,改变页面内容. 测试语句: <script>alert(1)</s ...
- 记一次使用logmnr查找操作人流程
经常遇到开发的需求,帮我查一下是谁修改了表里面的记录,是谁对表进行了DDL操作,此类问题可以使用logmnr解决 1.根据操作时间定位归档日志 SELECT name FROM V$ARCHIVED_ ...
- DB2版本升级(V9.7升级到V11.1)
1.V11.1版本升级路线 DB2 11.1 可以将现有的 Db2 V9.7.Db2 V10.1 或 Db2 V10.5 实例和数据库直接升级到 Db2 V11.1.如果 Db2 服务器正在 Db2 ...
- Eclipse中给jar包导入JavaDoc的方法
原文转载自:http://blog.csdn.net/mr_von/article/details/7740138 在使用Java语言开发的过程中,开发人员经常需要用到一些开源的工具包.在使用别人的j ...
- Spring Validation 验证
基本配置 1.pom引入maven依赖 <dependency> <groupId>javax.validation</groupId> <artifactI ...
- 第2章_神经网络入门_2-5&2-6 数据处理与模型图构建
目录 神经元的TF实现 安装 神经网络的TF实现 神经元的TF实现 安装 版本: Python 2.7 tf 1.8.0 Linux 略 demo 神经网络的TF实现 # py36 tf 2.1. # ...
- STL_map和multimap容器
一.map/multimap的简介 map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对.它提供基于key的快速检索能力. map中key值是唯一的.集合中的元素按一定的顺 ...
- JavaScript中函数的this指向!
JavaScript的this的指向问题! 这是我自己敲的, 报错! <button>点击查看绑定事件的this指向!</button> <script> // 函 ...