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;
}

最新文章

  1. Android中常见的图片加载框架
  2. Oracle SQL函数
  3. [转]双数组TRIE树原理
  4. .net微信公众号开发——消息与事件
  5. python 多线程就这么简单(转)
  6. Lua语言的特别之处
  7. HBase协处理器统计表数据量
  8. dublin core实例
  9. 数据结构与算法分析——C语言描述
  10. 9月1日,请记得备好名片来PechaKucha Night和大家“闲聊” | Hi!设计
  11. android 集成百度地图
  12. LightOJ 1259 Goldbach`s Conjecture 素数打表
  13. Python 日志模块实例
  14. css gray,grayscale,css变灰兼容大部分浏览器
  15. WEB版一次选择多个文件进行批量上传(WebUploader)的解决方案
  16. mac &amp; ip
  17. The MathType Dll cannot be found 问题解决办法
  18. 判断Android 当前版本是否为debug版本
  19. Node入门教程(13)第十一章:mocha单元测试+should断言库+istanbul覆盖率测试+art-template
  20. github 首页不显示提交记录

热门文章

  1. windows-qt 使用mingw编译c++boost并使用
  2. Swagger API文档集中化注册管理
  3. 系统学习 Java IO (七)----字节数组流 ByteArrayInputStream/ByteArrayOutputStream
  4. 计算广告之CTR预测--PNN模型
  5. Java学习笔记——Socket实现文件传输
  6. 为什么现在这么多人开始学习Python?
  7. python面试题(-)可变数据类型与不可变数据类型
  8. 从0x00到0xFF的含义
  9. 简述vue中父子组件是怎样相互传递值的(基础向)
  10. Java设计模式学习笔记(二) 简单工厂模式