hdu 1542 线段树扫描(面积)
2016-04-01 22:17
302 查看
Atlantis
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 10208 Accepted Submission(s): 4351
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
/* hdu 1542 线段树扫描(面积) 给你n个矩形,求最终形成的图形的面积大小 数据不一定是整数,所以先对他们进行离散化处理 大致就是每次计算平行于x轴的两条相邻线之间的面积,我们已经知道了两条平行 线之间的高度,于是就转变成在求当前情况下映射到x轴上的线段的长度,这个便能 利用线段树解决了 先把所有平行于x轴的线段按高度排序,然后从下往上,每次在遇到矩形下边时在 [l,r]上加1表示线段覆盖,遇到上边则填上-1消除影响.然后每次计算覆盖长度 再乘上高即可 参考(图文详解): http://www.cnblogs.com/scau20110726/archive/2013/04/12/3016765.html hhh-2016-03-26 17:58:50 */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <functional> using namespace std; #define lson (i<<1) #define rson ((i<<1)|1) typedef long long ll; const int maxn = 10005; double hs[maxn]; struct node { int l,r; double len; int sum; int mid() { return (l+r)>>1; } } tree[maxn*5]; void push_up(int i) { if(tree[i].sum) { tree[i].len = (hs[tree[i].r+1]-hs[tree[i].l]); } else if(tree[i].l == tree[i].r) { tree[i].len= 0; } else { tree[i].len = tree[lson].len+tree[rson].len; } } void build(int i,int l,int r) { tree[i].l = l; tree[i].r = r; tree[i].sum = tree[i].len = 0; if(l == r) return ; int mid = tree[i].mid(); build(lson,l,mid); build(rson,mid+1,r); push_up(i); } void push_down(int i) { } void Insert(int i,int l,int r,int val) { if(tree[i].l >= l && tree[i].r <=r ) { tree[i].sum += val; push_up(i); return ; } int mid = tree[i].mid(); push_down(i); if(l <= mid) Insert(lson,l,r,val); if(r > mid) Insert(rson,l,r,val); push_up(i); } struct edge { double l,r,high; int va; edge() {}; edge(double _l,double _r,double _high,int _va):l(_l),r(_r),high(_high),va(_va) {} }; edge tx[maxn*2]; bool cmp(edge a,edge b) { if(a.high != b.high) return a.high < b.high; else return a.va > b.va; } int tot,m; int fin(double x) { int l = 0,r = m-1; while(l <= r) { int mid = (l+r)>>1; if(hs[mid] == x) return mid; else if(hs[mid] < x) l = mid+1; else r = mid-1; } } int main() { int n; int cas =1; while(scanf("%d",&n) != EOF && n) { double x1,x2,y1,y2; tot = 0; for(int i = 1; i <= n; i++) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); hs[tot] = x1; tx[tot++] = edge(x1,x2,y1,1); hs[tot] = x2; tx[tot++] = edge(x1,x2,y2,-1); } sort(tx,tx+tot,cmp); sort(hs,hs+tot); m = 1; for(int i = 1;i < tot;i++) { if(hs[i] != hs[i-1]) hs[m++] = hs[i]; } build(1,0,m); double ans = 0; for(int i = 0;i < tot;i++) { int l = fin(tx[i].l); int r = fin(tx[i].r)-1; Insert(1,l,r,tx[i].va); ans += (tree[1].len)*(tx[i+1].high-tx[i].high); //cout << ans <<endl; } printf("Test case #%d\n",cas++); printf("Total explored area: %.2f\n\n",ans); } return 0; }
相关文章推荐
- 今天遇到一个poi导入的问题 参考别人的写了一个
- 你离顶尖Java程序员,只差这11本书的距离
- hdu 1542 线段树扫描(面积)
- Redhat Openshift云平台注册使用
- [android] 加载大图片到内存
- FZU 2102 Solve equation(规律题)
- 解决Android Studio添加依赖时出现“Manifest merger failed”错误
- MySQL学习笔记之多表连接
- spark访问redis集群中某个数据库的问题
- 1.PHP数据库陷阱
- springboot-shiro chapter02——springboot webmvc jsp
- 设计模式:visitor
- MySQL性能调优my.cnf详解
- 【matlab】:颜色模型的分类及颜色模型的转换简介
- ubuntu系统安装Matlab2014a
- 【JQuery】text()和html()的区别
- zabbix使用zabbix 数据库做数据分表
- RMQ (Range Minimum/Maximum Query)算法
- 13. Roman to Integer
- hdu 1828 线段树扫描线(周长)