【t009】最大矩形面积
Time Limit: 2 second
Memory Limit: 32 MB
【问题描述】
在x轴上水平放置着N个矩形,每个矩形都有相同的宽度,但是它们的高度并不相同。
比如,图1包含的矩形的高分别为2,1,4,5,1,3,3单位长度,矩形的宽为1单位长度。
你的任务就是计算柱状图中以x轴为底边的最大矩形的面积。图2阴影部分就是上述例子的最大矩形面积。
【输入格式】
输入数据的第一行是一个整数N(1≤N≤100,000),表示柱状图包含N个矩形。紧接着N个整数h1,...,hn(0≤hi≤20,000, 1≤i≤N),表示柱状图中按从左到右顺序给出的矩形的高度。矩形的宽度为1。
【输出格式】
输出一行一个整数S,表示以x轴为底边的最大矩形的面积。
【输入样例1】
7 2 1 4 5 1 3 3
【输出样例1】
8
【输入样例2】
4 1000 1000 1000 1000
【输出样例2】
4000
【题目链接】:http://noi.qz5z.com/viewtask.asp?id=t009
【题解】
方法是枚举第i个矩形为所有矩形中最低点;看看往左往右能取多少个矩形;
用一个单调队列搞, 处理出第i个矩形能往前取多远,能往后取多远;
每次枚举到第i个矩形的时候先和前一个矩形的高度比较;
如果比前一个高,则以第i个矩形为最低的情况最左只能取到第i个本身;并把这个矩形加入到单调队列中(单增);
如果比前一个矮,那么就往单调队列中的前面找到第一个比第i矩形矮的矩形,并在这个过程中不断把队尾比它大的元素pop掉;
可以看到,②号矩形前面的两个矩形都比②号高,而②号后面如果还有一个矩形比②号低,那么它往前找比它低的矩形的时候,中间那两个矩形就没必要再找了,直接跳过就好;
如上图,中间那3个矩形也可以划掉了;
可以看到我们在维护一个单调队列;
程序1是单调队列(100分);
程序2是用线段树+二分优化的枚举(要3s才能过全部数据,所以只得70分);
【完整代码】
/*
程序1
*/
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <string>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
void rel(LL &r)
{
r = 0;
char t = getchar();
while (!isdigit(t) && t!='-') t = getchar();
LL sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
}
void rei(int &r)
{
r = 0;
char t = getchar();
while (!isdigit(t)&&t!='-') t = getchar();
int sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
}
const int MAXN = 1e5+100;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
int n;
int a[MAXN],l[MAXN],r[MAXN];
int len,f[MAXN];
int main()
{
//freopen("F:\\rush.txt","r",stdin);
while (scanf("%d",&n)!=EOF)
{
rep1(i,1,n)
scanf("%d",&a[i]);
rep1(i,1,n)
{
if (len==0)
{
f[++len] = i;
l[i]=1;
}
while (len >=1 && a[i]<=a[f[len]]) len--;
if (len==0)
{
f[++len] = i;
l[i] = 1;
}
else
{
l[i] = f[len]+1;
f[++len] = i;
}
}
len = 0;
rep2(i,n,1)
{
while (len >=1 && a[i]<=a[f[len]]) len--;
if (len==0)
{
f[++len] = i;
r[i] = n;
}
else
{
r[i] = f[len]-1;
f[++len] = i;
}
}
int ans = 0;
rep1(i,1,n)
{
int len = r[i]-l[i]+1;
ans = max(len*a[i],ans);
}
printf("%d\n",ans);
}
return 0;
}
/*
程序2
*/
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <string>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
void rel(LL &r)
{
r = 0;
char t = getchar();
while (!isdigit(t) && t!='-') t = getchar();
LL sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
}
void rei(int &r)
{
r = 0;
char t = getchar();
while (!isdigit(t)&&t!='-') t = getchar();
int sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
}
const int MAXN = 1e5+10;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
int n,nn=0;
int a[MAXN],mi[MAXN<<2];
void build(int l,int r,int rt)
{
if (l==r)
{
scanf("%d",&a[++nn]);
mi[rt] = a[nn];
return;
}
int m = (l+r)>>1;
build(lson);
build(rson);
mi[rt] = min(mi[rt<<1],mi[rt<<1|1]);
}
int Q(int L,int R,int l,int r,int rt)
{
if (L<=l && r <=R)
return mi[rt];
int temp1 = 21e8,temp2 = 21e8;
int m = (l+r)>>1;
if (L <= m)
temp1 = Q(L,R,lson);
if (m < R)
temp2 = Q(L,R,rson);
return min(temp1,temp2);
}
int main()
{
//freopen("F:\\rush.txt","r",stdin);
int ans = 0;
scanf("%d",&n);
build(1,n,1);
rep1(i,1,n)
if (a[i]*n>ans)
{
int l,r,ans1=-1,ans2=-1;
l = 1,r = i-1;
while (l<=r)
{
int m = (l+r)>>1;
int d = Q(m,r,1,n,1);
if (d>=a[i])
ans1 = m,r = m-1;
else
l = m+1;
}
l = i+1,r = n;
while (l<=r)
{
int m = (l+r)>>1;
int d = Q(l,m,1,n,1);
if (d>=a[i])
ans2 = m,l = m+1;
else
r = m-1;
}
int ll,rr;
ll = (ans1==-1)?i:ans1;
rr = (ans2==-1)?i:ans2;
int s = (rr-ll+1)*a[i];
ans = max(ans,s);
}
printf("%d\n",ans);
return 0;
}
【t009】最大矩形面积的更多相关文章
- [LeetCode] Rectangle Area 矩形面积
Find the total area covered by two rectilinear rectangles in a2D plane. Each rectangle is defined by ...
- POJ 1151 Atlantis(线段树-扫描线,矩形面积并)
题目链接:http://poj.org/problem?id=1151 题目大意:坐标轴上给你n个矩形, 问这n个矩形覆盖的面积 题目思路:矩形面积并. 代码如下: #include<stdio ...
- 25.按要求编写一个Java应用程序: (1)编写一个矩形类Rect,包含: 两个属性:矩形的宽width;矩形的高height。 两个构造方法: 1.一个带有两个参数的构造方法,用于将width和height属性初化; 2.一个不带参数的构造方法,将矩形初始化为宽和高都为10。 两个方法: 求矩形面积的方法area() 求矩形周长的方法perimeter() (2)通过继承Rect类编写一个具有
package zhongqiuzuoye; //自己写的方法 public class Rect { public double width; public double height; Rect( ...
- 扫描线 + 线段树 : 求矩形面积的并 ---- hnu : 12884 Area Coverage
Area Coverage Time Limit: 10000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit user ...
- 【HDU 1542】Atlantis(线段树+离散化,矩形面积并)
求矩形面积并,离散化加线段树. 扫描线法: 用平行x轴的直线扫,每次ans+=(下一个高度-当前高度)*当前覆盖的宽度. #include<algorithm> #include<c ...
- 2015baidu复赛 矩形面积(包凸 && ps:附quickhull模板)
矩形面积 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 2015年百度之星初赛(1) --- F 矩形面积
矩形面积 Problem Description 小度熊有一个桌面,小度熊剪了很多矩形放在桌面上,小度熊想知道能把这些矩形包围起来的面积最小的矩形的面积是多少. Input 第一行一个正整数 T, ...
- POJ 1151 / HDU 1542 Atlantis 线段树求矩形面积并
题意:给出矩形两对角点坐标,求矩形面积并. 解法:线段树+离散化. 每加入一个矩形,将两个y值加入yy数组以待离散化,将左边界cover值置为1,右边界置为2,离散后建立的线段树其实是以y值建的树,线 ...
- POJ 1151 Atlantis 线段树求矩形面积并 方法详解
第一次做线段树扫描法的题,网搜各种讲解,发现大多数都讲得太过简洁,不是太容易理解.所以自己打算写一个详细的.看完必会o(∩_∩)o 顾名思义,扫描法就是用一根想象中的线扫过所有矩形,在写代码的过程中, ...
随机推荐
- local-语言切换监听事件
今天在更改时钟的问题的时候,需要监听语言切换来刷新时钟的显示.记录下监听方法 //注册监听事件 intentFilter.addAction(Intent.ACTION_LOCALE_CHANGED) ...
- Mysql数据库存储引擎--转
原文地址:http://pangge.blog.51cto.com/6013757/1303893 简单介绍 存储引擎就是指表的类型.数据库的存储引擎决定了表在计算机中的存储方式.存储引擎的概念是My ...
- 【问题】VUE 同一页面路由参数变化,数据不刷新
依赖路由的params参数获取写在created生命周期里面,因为相同路由二次甚至多次加载的关系 没有达到监听,退出页面再进入另一个页面并不会运行created组件生命周期,导致数据还是第一次进入的数 ...
- BZOJ1396: 识别子串(后缀自动机,线段树)
Description Input 一行,一个由小写字母组成的字符串S,长度不超过10^5 Output L行,每行一个整数,第i行的数据表示关于S的第i个元素的最短识别子串有多长. Sample I ...
- Vue+TypeScript学习
Vue CLI 内置了 TypeScript 工具支持.在 Vue 的下一个大版本 (3.x) 中也计划了相当多的 TypeScript 支持改进,包括内置的基于 class 的组件 API 和 TS ...
- 【MongoDB】在windows平台下mongodb的分片集群(六)
在本篇博客中我们主要讨论下博客的管理.因为已经在前面五篇中写了具体的实例,因此这里就不再举例说明. 一.监控 分片集群是整个体系中比較复杂的一块,因此更应该须要监控. 主要命令: serverstat ...
- amazeui学习笔记一(开始使用3)--兼容性列表compatibility
amazeui学习笔记一(开始使用3)--兼容性列表compatibility 一.总结 1.不要用ie做前端测试,不要碰ie,尽量用google 浏览器: 按照微软官方的说法,IE 开发者工具中的浏 ...
- 最小二乘法,python3实现
https://www.cnblogs.com/BlogOfMr-Leo/p/8627311.html [用的是库函数] https://blog.csdn. ...
- 【河南省多校脸萌第六场 B】点兵点将
[链接]点击打开链接 [题意] 在这里写题意 [题解] 先每个单位都不建造bi; 打死一个ai之后,把bi加入到大根堆里面. 然后等到不够打死某个单位的时候; 从大根堆里面取出最大的那个bi;不断取, ...
- Altium Designer四层板起步
参考转自:https://www.cnblogs.com/raymon-tec/p/5631318.html 双层板:一个是Top layer,一个是Bottom layer,layer层是信号层,也 ...