HDU1542 扫描线(矩形面积并)
Atlantis
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 18275 Accepted Submission(s): 7409
are several ancient Greek texts that contain descriptions of the fabled
island Atlantis. Some of these texts even include maps of parts of the
island. But unfortunately, these maps describe different regions of
Atlantis. Your friend Bill has to know the total area for which maps
exist. You (unwisely) volunteered to write a program that calculates
this quantity.
input file consists of several test cases. Each test case starts with a
line containing a single integer n (1<=n<=100) of available maps.
The n following lines describe one map each. Each of these lines
contains four numbers x1;y1;x2;y2
(0<=x1<x2<=100000;0<=y1<y2<=100000), not necessarily
integers. The values (x1; y1) and (x2;y2) are the coordinates of the
top-left resp. bottom-right corner of the mapped area.
The input file is terminated by a line containing a single 0. Don’t process it.
each test case, your program should output one section. The first line
of each section must be “Test case #k”, where k is the number of the
test case (starting with 1). The second one must be “Total explored
area: a”, where a is the total explored area (i.e. the area of the union
of all rectangles in this test case), printed exact to two digits to
the right of the decimal point.
Output a blank line after each test case.
10 10 20 20
15 15 25 25.5
0
Total explored area: 180.00
题意
解题思路
离散化x轴,然后扫描线,具体实现看代码
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=+;
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){
if(cnt[x]) sum[x]=Hash[r+]-Hash[l];//表示该区间整个线段长度可作为底边
else if(l==r) sum[x]=;//叶子结点区间长度为0,则底边长度为0
else sum[x]=sum[x*]+sum[x*+];
} void update(int x,int L,int R,int f,int l,int r){
if(L<=l&&r<=R){
cnt[x]+=f;
pushup(x,l,r);
return ;
}
int mid=(l+r)/;
if(L<=mid) update(x*,L,R,f,l,mid);
if(R>mid) update(x*+,L,R,f,mid+,r);
pushup(x,l,r);
} int main(){
double x1,x2,y1,y2; int p=;
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;
s[k++]=node(x1,x2,y1,);
Hash[k]=x2;
s[k++]=node(x1,x2,y2,-);
}
sort(s,s+k);//把线段按高度h从小到大排序
sort(Hash,Hash+k);//把x坐标从小到大排序 int ans=unique(Hash,Hash+k)-Hash;//去重复端点
double SUM=;
printf("Test case #%d\n",++p);
for(int i=;i<k;i++){
int l=lower_bound(Hash,Hash+ans,s[i].l)-Hash;
int r=lower_bound(Hash,Hash+ans,s[i].r)-Hash;
update(,l,r-,s[i].f,,ans-);//扫描线段更新可用底边长
SUM+=sum[]*(s[i+].h-s[i].h);//新增加面积 }
printf("Total explored area: %.2f\n\n",SUM);
}
return ;
}
HDU1542 扫描线(矩形面积并)的更多相关文章
- [HDU 4419] Colourful Rectangle (扫描线 矩形面积并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4419 题目大意:比矩形面积并多了颜色,问染成的每种颜色的面积. 矩形面积并的扫描线维护的是长度,这道题 ...
- poj 3277 City Horizon (线段树 扫描线 矩形面积并)
题目链接 题意: 给一些矩形,给出长和高,其中长是用区间的形式给出的,有些区间有重叠,最后求所有矩形的面积. 分析: 给的区间的范围很大,所以需要离散化,还需要把y坐标去重,不过我试了一下不去重 也不 ...
- HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)
版权声明:欢迎关注我的博客.本文为博主[炒饭君]原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349 P ...
- HDU1542 Atlantis(矩形面积并)
#pragma warning (disable:4996) #include<iostream> #include<cstring> #include<string&g ...
- [Codevs] 矩形面积求并
http://codevs.cn/problem/3044/ 线段树扫描线矩形面积求并 基本思路就是将每个矩形的长(平行于x轴的边)投影到线段树上 下边+1,上边-1: 然后根据线段树的权值和与相邻两 ...
- hdu1542 矩形面积并(线段树+离散化+扫描线)
题意: 给你n个矩形,输入每个矩形的左上角坐标和右下角坐标. 然后求矩形的总面积.(矩形可能相交). 题解: 前言: 先说说做这道题的感受: 刚看到这道题顿时就懵逼了,几何 烂的渣渣.后来从网上搜题解 ...
- HDU 1542"Atlantis"(线段树+扫描线求矩形面积并)
传送门 •题意 给你 n 矩形,每个矩形给出你 $(x_1,y_1),(x_2,y_2)$ 分别表示这个矩形的左下角和右上角坐标: 让你求这 n 个矩形并的面积: 其中 $x \leq 10^{5} ...
- hdu 1542 扫描线求矩形面积的并
很久没做线段树了 求矩形面积的并分析:1.矩形比较多,坐标也很大,所以横坐标需要离散化(纵坐标不需要),熟悉离散化后这个步骤不难,所以这里不详细讲解了,不明白的还请百度2.重点:扫描线法:假想有一条扫 ...
- HDU 3265 扫描线(矩形面积并变形)
Posters Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
随机推荐
- ABAP-表中数据的横向累加
GLT0 等表中数据的横向累加 ——塞依SAP培训 在 ABAP 的 GLT0.FAGLFLEXT 等余额表中,用诸如 TSL01.TSL02 …… TSL16 等字段记录了 16 个期间的发生额 ...
- python中并发编程基础1
并发编程基础概念 1.进程. 什么是进程? 正在运行的程序就是进程.程序只是代码. 什么是多道? 多道技术: 1.空间上的复用(内存).将内存分为几个部分,每个部分放入一个程序,这样同一时间在内存中就 ...
- python学习记录
学习python中······· 今天写了个装饰器用来登录用,用户名和密码是存在文件里的,涉及到了装饰器和带参数的装饰器 文件里的内容如下 {"liming": 123456} { ...
- Java语法 [HelloWorld]
程序代码: public class lqx {// AAAAANBBBBCKJKSLJIOQL/*请手打哦!*/ public static void main (String[] args) { ...
- [C语言]进阶|数据类型: 整数, 浮点, 逻辑, 类型转换和条件运算
--------------------------------------------------------------------------------- [C语言的类型] 1. 整型(都分为 ...
- javascript正则表达式中 (?=exp)、(?<=exp)、(?!exp)
(?=exp) 百度百科给的解释:非获取匹配,正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用.例如,“Windows(?=95|98|NT|2000) ...
- Java学习笔记(十三):package关键字
- mysql case when then else end 写法
今天改SQL用到了就搜了搜,现在记下来. case when tableName.type in (1,2,3,4) and tableName.state in (5,6) then 1 when ...
- [Java核心技术]第四章-对象与类(4.1-4.6总结)
4.1面向对象程序设计概述 OOP(面向对象编程Object Oriented Programming) OOP中数据第一位,算法第二位. 类 封装:关键在于不能让其他方法直接访问类的实例域,程序仅通 ...
- 解决在jupyter notebook中遇到的ImportError: matplotlib is required for plotting问题
昨天学习pandas和matplotlib的过程中, 在jupyter notebook遇到ImportError: matplotlib is required for plotting错误, 以下 ...