Second Large Rectangle

题目传送门

解题思路

先求出每个点上的高,再利用单调栈分别求出每个点左右两边第一个高小于自己的位置,从而而得出最后一个大于等于自己的位置,进而求出自己的位置的高为高,这个点所在的边为底的最大矩形。这些求出的矩形中的最大值即为可求出的最大矩形。而次大值可能是这些矩形之一,也可能是这些矩形的高减1或者宽减1得到的矩形。所以把这些全都记录下来,第二大的即为答案。由于这样求出的矩形会有重复,所以记录一下坐标来去重。

代码如下

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll; inline int read(){
int res = 0, w = 0; char ch = 0;
while(!isdigit(ch)){
w |= ch == '-', ch = getchar();
}
while(isdigit(ch)){
res = (res << 3) + (res << 1) + (ch ^ 48);
ch = getchar();
}
return w ? -res : res;
} const int N = 1005;
int a[N][N], h[N][N];
int l[N][N], r[N][N];
struct T{
int val, i;
T(int val, int i): val(val), i(i){}
};
struct R{
int s, x, y, r;
R(){}
R(int s, int x, int y, int r): s(s), x(x), y(y), r(r){}
bool operator<(const R& a)const{
if(s != a.s)
return s < a.s;
else if(x != a.x)
return x < a.x;
else if(y != a.y)
return y < a.y;
else
return r < a.r;
}
};
int main()
{
int n, m;
scanf("%d%d%*c", &n, &m);
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= m; j ++){
char ch = getchar();
a[i][j] = ch - '0';
}
getchar();
}
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= m; j ++){
if(a[i][j])
h[i][j] = h[i - 1][j] + 1;
else
h[i][j] = 0;
}
}
for(int i = 1; i <= n; i ++){
stack<T> sta1;
for(int j = 1; j <= m; j ++){
while(!sta1.empty() && sta1.top().val >= h[i][j])
sta1.pop();
if(!sta1.empty())
l[i][j] = sta1.top().i + 1;
else
l[i][j] = 1;
sta1.push(T(h[i][j], j));
}
stack<T> sta2;
for(int j = m; j >= 1; j --){
while(!sta2.empty() && sta2.top().val >= h[i][j])
sta2.pop();
if(!sta2.empty())
r[i][j] = sta2.top().i - 1;
else
r[i][j] = m;
sta2.push(T(h[i][j], j));
}
}
priority_queue<R> pq;
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= m; j ++){
if(!a[i][j])
continue;
pq.push(R((r[i][j] - l[i][j] + 1) * h[i][j], i, l[i][j], r[i][j]));
pq.push(R((r[i][j] - l[i][j]) * h[i][j], i, l[i][j], r[i][j] - 1));
pq.push(R((r[i][j] - l[i][j] + 1) * (h[i][j] - 1), i, l[i][j], r[i][j]));
}
}
R top;
if(!pq.empty()){
top = pq.top();
pq.pop();
}
while(!pq.empty()){
R t = pq.top();
pq.pop();
if(t.s != top.s || t.x != top.x || t.y != top.y || t.r != top.r){
cout << t.s << endl;
return 0;
}
}
cout << 0 << endl;
return 0;
}

2019牛客多校第二场H-Second Large Rectangle的更多相关文章

  1. 2019 牛客多校第二场 H Second Large Rectangle

    题目链接:https://ac.nowcoder.com/acm/contest/882/H 题目大意 给定一个 n * m 的 01 矩阵,求其中第二大的子矩阵,子矩阵元素必须全部为 1.输出其大小 ...

  2. 牛客多校第二场H Second Large Rectangle 单调栈or悬线法

    Second Large Rectangle 题意 给出n*m的01矩阵,问由1组成的第二大的矩阵的大小是多少? 分析 单调栈(or 悬线法)入门题 单调栈 预处理出每一个点的最大高度,然后单调栈每一 ...

  3. 2019牛客多校第二场H题(悬线法)

    把以前的题补补,用悬线求面积第二大的子矩形.我们先求出最大子矩阵的面积,并记录其行三个方向上的悬线长度.然后排除这个矩形,记得还得特判少一行或者少一列的情况 #include <bits/std ...

  4. 2019牛客多校第二场 A Eddy Walker(概率推公式)

    2019牛客多校第二场 A Eddy Walker(概率推公式) 传送门:https://ac.nowcoder.com/acm/contest/882/A 题意: 给你一个长度为n的环,标号从0~n ...

  5. 2019 牛客暑期多校 第二场 H Second Large Rectangle (单调栈)

    题目:https://ac.nowcoder.com/acm/contest/882/H 题意:一个大的01矩阵,然后现在要求第二大的全一矩阵是多少 思路:在这里我们首先学习一下另一个东西,怎么求直方 ...

  6. 2019年牛客多校第二场 H题Second Large Rectangle

    题目链接 传送门 题意 求在\(n\times m\)的\(01\)子矩阵中找出面积第二大的内部全是\(1\)的子矩阵的面积大小. 思路 处理出每个位置往左连续有多少个\(1\),然后对每一列跑单调栈 ...

  7. [2019牛客多校第二场][G. Polygons]

    题目链接:https://ac.nowcoder.com/acm/contest/882/G 题目大意:有\(n\)条直线将平面分成若干个区域,要求处理\(m\)次询问:求第\(q\)大的区域面积.保 ...

  8. 2019牛客多校第二场D-Kth Minimum Clique

    Kth Minimum Clique 题目传送门 解题思路 我们可以从没有点开始,把点一个一个放进去,先把放入一个点的情况都存进按照权值排序的优先队列,每次在新出队的集合里增加一个新的点,为了避免重复 ...

  9. 2019牛客多校第二场F-Partition problem(搜索+剪枝)

    Partition problem 题目传送门 解题思路 假设当前两队的对抗值为s,如果把红队中的一个人a分配到白队,s+= a对红队中所有人的对抗值,s-= a对白队中所有人的对抗值.所以我们可以先 ...

随机推荐

  1. 分布式存储系统GlusterFS初体验

    摘要: GlusterFS是Scale-Out存储解决方案Gluster的核心,它是一个开源的分布式文件系统,具有强大的横向扩展能力,通过扩展能够支持数PB存储容量和处理数千客户端.GlusterFS ...

  2. 15个非常棒的jQuery无限滚动插件【瀑布流效果】

    现在,最热门的网站分页趋势之一是jQuery的无限滚动(也即瀑布流).如果你碰巧观察Pinterest的网站,如Facebook,Twitter和deviantART的,你会发现无限滚动的动作,当旧的 ...

  3. rem.js移动布局实例教程

    最近想买需要开发微站,微信公众号内嵌入的移动web,总结方法可以使用css3直接使用百分比布局,也可以使用bootstrap做响应式布局等多种方法,个人感觉看项目需要,笔者使用rem.js进行移动前端 ...

  4. 简单解说Linux命令输出与命令替换

    Linux命令能提高更方便的使用性能.下面就这就来讲术Linux命令.将一个程序或Linux命令的输出作为另一个程序或命令的输入,有两种方法,一种是通过一个临时文件将两个命令或程序结合在一起,例如上个 ...

  5. python网络编程——实现简单聊天

    通过socket建立简单的聊天工具 server.py import socket import threading import time s = socket.socket(socket.AF_I ...

  6. 宜信开源|数据库审核软件Themis的规则解析与部署攻略

    一.介绍 Themis是宜信公司DBA团队开发的一款数据库审核产品,可帮助DBA.开发人员快速发现数据库质量问题,提升工作效率.其名称源自希腊神话中的正义与法律女神.项目取此名称,寓意此平台对数据库质 ...

  7. 智能小程序关于Filter过滤器的简单使用

    <filter module="swan"> export default { imgurl: (imgUrl) => { var imgurlprefix = ...

  8. spring 5.x 系列第13篇 —— 整合RabbitMQ (xml配置方式)

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.说明 1.1 项目结构说明 本用例关于rabbitmq的整合提供简单消 ...

  9. 漫谈Redis分布式锁实现

    在Redis上,可以通过对key值的独占来实现分布式锁,表面上看,Redis可以简单快捷通过set key这一独占的方式来实现分布式锁,也有许多重复性轮子,但实际情况并非如此.总得来说,Redis实现 ...

  10. 7天入门Linux

    经过一个星期学习,Linux终于入门了,在这里小记下~ =====================分割线============================= Ubuntu常用命令: ctrl+s ...