Atlantis

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 8998    Accepted Submission(s): 3856

Problem Description
There 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
The 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.
 
Output
For 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.
 
Sample Input
2
10 10 20 20
15 15 25 25.5
0
 
Sample Output
Test case #1
Total explored area: 180.00
所谓的离散化,大家能够简单的理解为,将一组非常大的数据,浓缩为一组非常小的数据,用这组数据来取代原数据的作用,
比方给你1000个数,数的范围为(1,1e18)我们这里就能够用离散化,因为仅仅有1000个数。我们能够用一个数组的下标代表提供的每一数。假设须要这个数据了,因为是下标,能够直接通过下标获得,如此就是离散化。
扫描线的知识提供一个大牛的博客:http://www.cnblogs.com/scau20110726/archive/2013/04/12/3016765.html
讲得非常基础,是个非常不错的博客
然后提醒一下这个扫描线要注意的问题就是区间的问题
一般的线段树以及我们的区间改动合并。都有一个共同点,就是不会出现区间缺失的现象,什么叫区间缺失。顾名思义,区间缺失就是缺少一些区间没有进行运算,这里的扫描线就会遇到这个问题。
普遍的,我们的线段树以及数据区间分布是这种:
[1, a][a + 1, b][b + 1, c][c + 1, d][d + 1, e].......
可是假设仅仅是简简单单的用这个来解决扫描线的问题会导致错误,为什么因为。他没有涉及到[a,a + 1],在扫描线中会出现[a,a + 1]中的数据,而经常使用的线段树的区间概念是无法解决这种问题的,出现了所谓的区间缺失,如何解决,以下的代码给出了解决方式,这里简单的提一下,就是利用[ , ),这个区间性质,左闭右开。就可以解决区间缺失问题
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
typedef long long LL;
#define lson rt << 1, l, mid
#define rson rt << 1|1, mid + 1, r
const int MAXN = 2000 + 5;
int Col[MAXN << 2], n, cnt, res;
double X[MAXN << 2], Sum[MAXN << 2];
struct seg {
double l,r,h;
int s;
seg() {}
seg(double l,double r,double h,int s):l(l),r(r),h(h),s(s) {}
bool operator < (const seg & object) const {
return h < object.h;
}
} S[MAXN]; void pushup(int rt,int l,int r) {
if (Col[rt]) Sum[rt] = X[r+1] - X[l];//利用[ , ),这个区间性质。左闭右开
else if (l == r) Sum[rt] = 0;
else Sum[rt] = Sum[rt<<1] + Sum[rt<<1|1];
} void update(int L, int R, int c,int rt,int l, int r) {
if(L <= l && r <= R) {
Col[rt] += c;
pushup(rt,l,r);
return ;
}
int mid = (l + r) >> 1;
if(L <= mid) update(L, R, c, lson);
if(R > mid) update(L, R, c, rson);
pushup(rt,l,r);
} int binary_find(double x){
int lb = -1,ub = res - 1;
while(ub - lb > 1){
int mid = (lb + ub) >> 1;
if(X[mid] >= x) ub = mid;
else lb = mid;
}
return ub;
} int main() {
int cas = 1;
while(~ scanf("%d", &n), n) {
cnt = res = 0;
for(int i = 0 ; i < n; i ++) {
double a,b,c,d;
scanf("%lf%lf%lf%lf",&a, &b, &c,&d);
S[cnt] = seg(a, c, b, 1);
X[cnt ++] = a;
S[cnt] = seg(a, c, d, -1);
X[cnt ++] = c;
}
sort(X, X + cnt);
sort(S, S + cnt);
res ++;
for(int i = 1; i < cnt; i ++) {
if(X[i] != X[i - 1]) X[res ++] = X[i];
} memset(Sum, 0, sizeof(Sum));
memset(Col, 0, sizeof(Col));
double ans = 0;
for(int i = 0;i < cnt - 1;i ++){
int l = binary_find(S[i].l);
int r = binary_find(S[i].r) - 1;//利用[ , ),这个区间性质,左闭右开
update(l, r, S[i].s, 1, 0, res - 1);
ans += Sum[1] * (S[i + 1].h - S[i].h);
}
printf("Test case #%d\nTotal explored area: %.2lf\n\n",cas++ , ans);
}
return 0;
}

 

HDU 1542 Atlantis (线段树 + 扫描线 + 离散化)的更多相关文章

  1. HDU 1542 - Atlantis - [线段树+扫描线]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...

  2. hdu 1542 Atlantis (线段树扫描线)

    大意: 求矩形面积并. 枚举$x$坐标, 线段树维护$[y_1,y_2]$内的边是否被覆盖, 线段树维护边时需要将每条边挂在左端点上. #include <iostream> #inclu ...

  3. hdu 1542 Atlantis(线段树,扫描线)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  4. HDU 1542 Atlantis(线段树面积并)

     描述 There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. S ...

  5. POJ 1151 / HDU 1542 Atlantis 线段树求矩形面积并

    题意:给出矩形两对角点坐标,求矩形面积并. 解法:线段树+离散化. 每加入一个矩形,将两个y值加入yy数组以待离散化,将左边界cover值置为1,右边界置为2,离散后建立的线段树其实是以y值建的树,线 ...

  6. Atlantis HDU - 1542 (线段树扫描线)

    There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...

  7. hdu 1542(线段树+扫描线 求矩形相交面积)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  8. hdu1542 Atlantis (线段树+扫描线+离散化)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  9. hdu 1542 Atlantis(段树&amp;扫描线&amp;面积和)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

随机推荐

  1. Dynamic Web Module版本对应tomcat版本

    MyEclipse2017+JDK 1.8环境下 Dynamic Web Module版本3.1要对应tomcat7.0以上版本,不然部署项目时会出现错误(会出现无法部署项目的情况). Dynamic ...

  2. 时间戳显示为多少分钟前,多少天前的JS处理

    /* ** 时间戳显示为多少分钟前,多少天前的处理 ** eg. ** console.log(dateDiff(1411111111111)); // 2014年09月19日 ** console. ...

  3. Ubuntu环境修改IP地址方法

    ubuntu环境修改IP地址方法和CentOS系统修改方法不太一样.ubuntu系统修改IP地址方法如下: 编辑/etc/network/interfaces,增加以下内容: auto eth0 if ...

  4. centos 简单用户管理

    一.配置文件 /etc/passwd:存放用户信息,以“:”分割成7个部分 1.账号名称,用来对应UID: 2.早期密码存放位置,后来密码改存/etc/shadow中,以“x”代替: 3.UID,使用 ...

  5. buf.toString()

    buf.toString([encoding[, start[, end]]]) encoding {String} 默认:'utf8' start {Number} 默认:0 end {Number ...

  6. 集训第五周动态规划 D题 LCS

    Description In a few months the European Currency Union will become a reality. However, to join the ...

  7. python——文件管理

    文件操作分为读.写.修改 一.读文件 f = open(file='D:/工作日常/兼职白领学生空姐模特护士联系方式.txt',mode='r',encoding='utf-8') data = f. ...

  8. Springboot开启事务

    参考资料: https://blog.csdn.net/message_lx/article/details/77584847

  9. Huawei-R&S-网络工程师实验笔记20190615-IP基础(AR201上配置IP)

    >Huawei-R&S-网络工程师实验笔记20190615-IP基础(AR201上配置IP) >>实验开始,先上拓扑图参考: >>>一般正常配置IP操作如下 ...

  10. python之字符串处理 2014-4-5

    #字符串 p62 13:20pm-15:20 上一章讲的所有的序列化操作对于字符串同样适用 不过字符串不可变 所以无法使用分片赋值 1.字符串格式化 >>> format=" ...