P1382 楼房 (扫描线,线段树)
题目描述
地平线(x轴)上有n个矩(lou)形(fang),用三个整数h[i],l[i],r[i]来表示第i个矩形:矩形左下角为(l[i],0),右上角为(r[i],h[i])。地平线高度为0。在轮廓线长度最小的前提下,从左到右输出轮廓线。
下图为样例2
输入输出格式
输入格式:
第一行一个整数n,表示矩形个数
以下n行,每行3个整数h[i],l[i],r[i]表示第i个矩形。
输出格式:
第一行一个整数m,表示节点个数
以下m行,每行一个坐标表示轮廓线上的节点。从左到右遍历轮廓线并顺序输出节点。第一个和最后一个节点的y坐标必然为0。
输入输出样例
【样例输入1】
2
3 0 2
4 1 3 【样例输入2】
5
3 -3 0
2 -1 1
4 2 4
2 3 7
3 6 8
【样例输出1】
6
0 0
0 3
1 3
1 4
3 4
3 0 【样例输出2】
14
-3 0
-3 3
0 3
0 2
1 2
1 0
2 0
2 4
4 4
4 2
6 2
6 3
8 3
8 0
说明
【数据范围】
对于30%的数据,n<=100
对于另外30%的数据,n<=100000,1<=h[i],l[i],r[i]<=1000
对于100%的数据,1<=n<=100000,1<=h[i]<=10^9,-10^9<=l[i]<r[i]<=10^9
思路
1.扫描线:
先把每个矩形拆成两条边,一条入边,一条出边,然后按照横坐标以及高度排序,同时还需要一个堆实时记录高度,然后一遍从左到右的遍历就可以求出每个交点和交点的个数,然后即可解.
2.离散化+线段树
(贼麻烦)...
上代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=;
int read()
{
char ch=getchar();int f=,w=;
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch<=''&&ch>=''){w=w*+ch-'';ch=getchar();}
return f*w;
} struct ls{
int up;
int x;
int k;
}l[maxn]; struct ss{
int ax;
int ay;
}ans[maxn*];
int n,cnt,num;
multiset<int>s; int cmp(ls i,ls j)
{
if(i.x!=j.x)return i.x<j.x;
if(i.k!=j.k)return i.k<j.k;
if(i.k==)return i.up>j.up;
if(i.k==)return i.up<j.up;
} int main(){
n=read();
for(int i=;i<=n;i++){
int h,ll,r;
h=read(),ll=read(),r=read();
l[++cnt].up=h; l[cnt].x=ll;l[cnt].k=;
l[++cnt].up=h; l[cnt].x=r,l[cnt].k=;
}
sort(l+,l+cnt+,cmp);
s.insert();
for(int i=;i<=cnt;i++){
int mx=*s.rbegin();
if(l[i].k==){
if(l[i].up<=mx) s.insert(l[i].up);
else{
++num;ans[num].ax=l[i].x;ans[num].ay=mx;
++num;ans[num].ax=l[i].x;ans[num].ay=l[i].up;
s.insert(l[i].up);
}
}
if(l[i].k==){
if(l[i].up==mx&&s.count(mx)==){
s.erase(mx);
ans[++num].ax=l[i].x; ans[num].ay=l[i].up;
ans[++num].ax=l[i].x;ans[num].ay=*s.rbegin();
}
else s.erase(s.find(l[i].up));
}
}
printf("%d\n",num);
for(int i=;i<=num;i++)
cout<<ans[i].ax<<' '<<ans[i].ay<<endl;
return ;
}
P1382 楼房 (扫描线,线段树)的更多相关文章
- HDU 3642 - Get The Treasury - [加强版扫描线+线段树]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3642 Time Limit: 10000/5000 MS (Java/Others) Memory L ...
- 【BZOJ3958】[WF2011]Mummy Madness 二分+扫描线+线段树
[BZOJ3958][WF2011]Mummy Madness Description 在2011年ACM-ICPC World Finals上的一次游览中,你碰到了一个埃及古墓. 不幸的是,你打开了 ...
- HDU 3265/POJ 3832 Posters(扫描线+线段树)(2009 Asia Ningbo Regional)
Description Ted has a new house with a huge window. In this big summer, Ted decides to decorate the ...
- 【bzoj4491】我也不知道题目名字是什么 离线扫描线+线段树
题目描述 给定一个序列A[i],每次询问l,r,求[l,r]内最长子串,使得该子串为不上升子串或不下降子串 输入 第一行n,表示A数组有多少元素接下来一行为n个整数A[i]接下来一个整数Q,表示询问数 ...
- hdu1542 Atlantis(扫描线+线段树+离散)矩形相交面积
题目链接:点击打开链接 题目描写叙述:给定一些矩形,求这些矩形的总面积.假设有重叠.仅仅算一次 解题思路:扫描线+线段树+离散(代码从上往下扫描) 代码: #include<cstdio> ...
- P3722 [AH2017/HNOI2017]影魔(单调栈+扫描线+线段树)
题面传送门 首先我们把这两个贡献翻译成人话: 区间 \([l,r]\) 产生 \(p_1\) 的贡献当且仅当 \(a_l,a_r\) 分别为区间 \([l,r]\) 的最大值和次大值. 区间 \([l ...
- BZOJ 2584: [Wc2012]memory(扫描线+线段树)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2584 题意:给出平面n个线段,任意两个线段严格不相交,且每个线段不平行于坐标轴.移 ...
- [BZOJ 1218] [HNOI2003] 激光炸弹 【n logn 做法 - 扫描线 + 线段树】
题目链接:BZOJ - 1218 题目分析 可以覆盖一个边长为 R 的正方形,但是不能包括边界,所以等价于一个边长为 R - 1 的正方形. 坐标范围 <= 5000 ,直接 n^2 的二维前缀 ...
- hdu4419 Colourful Rectangle 12年杭州网络赛 扫描线+线段树
题意:给定n个矩形,每个矩形有一种颜色,RGB中的一种.相交的部分可能为RG,RB,GB,RGB,问这n个矩形覆盖的面积中,7种颜色的面积分别为多少 思路:把x轴离散化做扫描线,线段树维护一个扫描区间 ...
随机推荐
- Expires和Cache-Control
本文原链接:https://blog.csdn.net/zhouziyu2011/article/details/71312452 浅谈前端性能优化(一)——Expires和Cache-Control ...
- polygon 画图
cityscape数据集,我现在想根据json文件中的polygon画出整个road的区域,这是运行的脚本.这个文件必须使用coco的pythonAPI的包,把这个脚本放在pythonAPI文件夹下就 ...
- 单核CPU并发与非并发测试
多线程运行程序的目的一般是提高程序运行效率并且能够提高硬件的利用率比如多核CPU,但是如果我们只有单核CPU并发运行程序会怎样呢? 我以两个环境作为对比: 环境A(我本机8c) 环境B(我的云服务器1 ...
- MySql数据库中where的使用
SELECT * from runoob_tbl WHERE runoob_author='菜鸟教程'; MySQL 的 WHERE 子句的字符串比较是不区分大小写的. 你可以使用 BINARY 关键 ...
- iOS 开发 Xib 的嵌套使用
最近公司项目需要使用 Xib 中嵌套 Xib来布局界面的, 研究了很久才实现!!! 分享给大家,希望帮助到更多的开发者...... 开发中自定义界面有两种方式 一: 纯代码实现 适合单个极度复杂的界面 ...
- 35. Search Insert Position@python
Given a sorted array and a target value, return the index if the target is found. If not, return the ...
- C语言输出多位小数
#include<stdio.h>#include<stdlib.h>int main(){int i=0;int m=19;int n=3;int s=0;s=m/n;pri ...
- PAT 乙级 1088
题目 题目链接:PAT 乙级 1088 题解 比较简单的一道题,下面来简单说说思路: 因为甲确定是一个两位数,因此通过简单的暴力循环求解甲的值,又根据题设条件“把甲的能力值的 2 个数字调换位置就是乙 ...
- vim中,在编辑模式下如何快速移动光标
编辑 ~/.vimrc 配置文件,加入如下行,编辑模式下自定义的快捷键 inoremap <C-o> <Esc>o inoremap <C-l> <Righ ...
- freertos知识点笔记——队列、二值信号量、计数信号量
队列1.队列queue通常用于任务之间的通信,一个任务写缓存,另一个任务读缓存.队列还会有等待时间,2.阻塞超时时间.如果在发送时队列已满,这个时间即是任务处于阻塞态等待队列空间有效的最长等待时间.如 ...