POJ 1177Picture 扫描线(若干矩形叠加后周长)
Picture
Description
Write a program to calculate the perimeter. An example with 7 rectangles is shown in Figure 1.

The corresponding boundary is the whole set of line segments drawn in Figure 2.

The vertices of all rectangles have integer coordinates.
Input
program is to read from standard input. The first line contains the
number of rectangles pasted on the wall. In each of the subsequent
lines, one can find the integer coordinates of the lower left vertex and
the upper right vertex of each rectangle. The values of those
coordinates are given as ordered pairs consisting of an x-coordinate
followed by a y-coordinate.
0 <= number of rectangles < 5000
All coordinates are in the range [-10000,10000] and any existing rectangle has a positive area.
Output
program is to write to standard output. The output must contain a
single line with a non-negative integer which corresponds to the
perimeter for the input rectangles.
Sample Input
7
-15 0 5 10
-5 8 20 25
15 -4 24 14
0 -6 16 4
2 15 10 22
30 10 36 20
34 0 40 16
Sample Output
228 题意
依次给出矩形左下角和右上角坐标,求若干矩形叠加后的周长。
解题思路
分别离散化x轴、y轴,然后做扫描线,一条扫x轴、一条扫y轴,累加即是周长。
//#include<bits/stdc++.h>
#include<map>
#include<set>
#include<ctime>
#include<cmath>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e4+;
int cnt[maxn*],n;//记录某个区间的下底边比上底边多的个数
double sum[maxn*];//记录某个区间下底边比上底边多的个数总长度
double Hash[][maxn];//对横坐标x离散化 struct node{
double l,r,h;
int f;
node(){}
node(double x1,double x2,double hh,int ff):l(x1),r(x2),h(hh),f(ff){}
bool operator<(const node &a)const{
return h<a.h;
}
}s[][maxn*]; void init(){
memset(sum,,sizeof(sum));
memset(cnt,,sizeof(cnt));
} void pushup(int x,int l,int r,int flag){
if(cnt[x]) sum[x]=Hash[flag][r+]-Hash[flag][l];//表示该区间整个线段长度可作为底边
else if(l==r) sum[x]=;//叶子结点区间长度为0,则底边长度为0
else sum[x]=sum[x*]+sum[x*+];
} void update(int x,int flag,int L,int R,int val,int l,int r){
if(L<=l&&r<=R){
cnt[x]+=val;
pushup(x,l,r,flag);
return ;
}
int mid=(l+r)/;
if(L<=mid) update(x*,flag,L,R,val,l,mid);
if(R>mid) update(x*+,flag,L,R,val,mid+,r);
pushup(x,l,r,flag);
} int main(){
double x1,x2,y1,y2;
while(cin>>n&&n){
init();int k=;
while(n--){
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
if(x1>x2) swap(x1,x2);
if(y1>y2) swap(y1,y2);
Hash[][k]=x1; Hash[][k]=y1;
s[][k]=node(x1,x2,y1,);s[][k]=node(y1,y2,x1,);
k++;
Hash[][k]=x2; Hash[][k]=y2;
s[][k]=node(x1,x2,y2,-); s[][k]=node(y1,y2,x2,-);
k++;
}
sort(s[],s[]+k);sort(s[],s[]+k);//把线段按高度h从小到大排序
sort(Hash[],Hash[]+k);sort(Hash[],Hash[]+k);//把x坐标从小到大排序 int ans1=unique(Hash[],Hash[]+k)-Hash[];//去重复端点
int ans2=unique(Hash[],Hash[]+k)-Hash[];
double SUM=,last; init();last=;
for(int i=;i<k;i++){
int l=lower_bound(Hash[],Hash[]+ans1,s[][i].l)-Hash[];
int r=lower_bound(Hash[],Hash[]+ans1,s[][i].r)-Hash[];
update(,,l,r-,s[][i].f,,ans1-);
SUM+=abs(sum[]-last);
last=sum[]; }
init();last=;
for(int i=;i<k;i++){
int l=lower_bound(Hash[],Hash[]+ans2,s[][i].l)-Hash[];
int r=lower_bound(Hash[],Hash[]+ans2,s[][i].r)-Hash[];
update(,,l,r-,s[][i].f,,ans2-);
SUM+=abs(sum[]-last);
last=sum[];
}
printf("%d\n",(int)SUM);
}
return ;
}
POJ 1177Picture 扫描线(若干矩形叠加后周长)的更多相关文章
- poj 1177 --- Picture(线段树+扫描线 求矩形并的周长)
题目链接 Description A number of rectangular posters, photographs and other pictures of the same shape a ...
- HDU-1828 Picture(扫描线 求矩形并的周长)
http://acm.hdu.edu.cn/showproblem.php?pid=1828 Time Limit: 6000/2000 MS (Java/Others) Memory Limi ...
- hdu1828 线段树扫描线求矩形面积的周长
题意: 给你n个矩形,问你这n个矩形所围成的图形的周长是多少. 思路: 线段树的扫描线简单应用,这个题目我用的方法比较笨,就是扫描两次,上下扫描,求出多边形的上下边长和,然后同 ...
- hdu 1542 扫描线求矩形面积的并
很久没做线段树了 求矩形面积的并分析:1.矩形比较多,坐标也很大,所以横坐标需要离散化(纵坐标不需要),熟悉离散化后这个步骤不难,所以这里不详细讲解了,不明白的还请百度2.重点:扫描线法:假想有一条扫 ...
- HDU 1828“Picture”(线段树+扫描线求矩形周长并)
传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...
- hdu 1255 覆盖的面积 (扫描线求矩形交)
覆盖的面积 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]
题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...
- poj 1177 Picture (线段树 扫描线 离散化 矩形周长并)
题目链接 题意:给出n个矩形,每个矩形给左下 和 右上的坐标,求围成的周长的长度. 分析: 首先感谢大神的博客,最近做题经常看大神的博客:http://www.cnblogs.com/kuangbin ...
- HDU 1828 扫描线(矩形周长并)
Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
随机推荐
- python -反射hasattr、setattr、delattr
login.py #!/usr/bin/dev python# coding:utf-8 def index(): print u'欢迎访问xx网站首页' def login(): print u'登 ...
- saltstack的封装和内网使用
0.客户端使用 linux:把linux的ragent文件夹拷贝到内网linux /opt目录下,运行初始化脚本 salt服务端:# @Master:"/opt/ragent/python/ ...
- MySQL innodb_autoinc_lock_mode 详解
innodb_autoinc_lock_mode这个参数控制着在向有auto_increment 列的表插入数据时,相关锁的行为: 通过对它的设置可以达到性能与安全(主从的数据一致性)的平衡 [0]我 ...
- uname命令详解
1.简介: uname命令用于打印当前系统相关信息(内核版本号.硬件架构.主机名称和操作系统类型等). 2.命令语法: uname (选项) 3.选项: -a或--all:显示全部的信息: -m或-- ...
- MySQL事件不自动执行
前台统计数据量很大,于是在数据库中新建了一个事件,每隔10分钟执行一次存储过程,向统计表中插入统计数据 但是创建完成后发现事件并不会自动执行,上网查了一下才知道必须手工开启才事件可以 查看事件开启状态 ...
- [leetcode]37. Sudoku Solver 解数独
Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy ...
- android的事件分发传递机制
事件的分发与传递最重要的三个处理方法是 dispatchTouchEvent onInterceptTouchEvent onTouchEvent 综合来说事件的 传递是由外层向里层传递,而处理是从里 ...
- strcpy函数用法
字符串是数组类型,不能通过赋值运算进行,要通过strcpy进行拷贝,其中目的字符串必须是字符串变量,源字符串可以是常量,复制后源字符串保持不变. strcpy()是C中的一个复制字符串的库函数,在C+ ...
- C语言输出格雷码
格雷码是以n位的二进制来表示数. 与普通的二进制表示不同的是,它要求相邻两个数字只能有1个数位不同. 首尾两个数字也要求只有1位之差. 有很多算法来生成格雷码.以下是较常见的一种: 从编码全0开始生成 ...
- BootStrap常用组件及响应式开发
BootStrap常用组件 PS:所有的代码必须写在<class="container/container-fluid">容器当中 常用组件包含内容: 字体图标 下拉菜 ...