杭电 HDU ACM 1225 Atlantis (线段树 扫描线 离散化 最基本)
2015-08-11 12:51
465 查看
acm第一发扫描线问题,其实算法原理很好理解 ,但是具体实现起来还是遇到诸多问题,我尝试参考了网上两份对于解决 线段树表示区间问题的方法, 第一种是每个结点的真实值,比如对于更新离散化后的1 ~ 4区间,我们在线段树中更新的是1 ~ 3,这样单个结点也可以表示一个最小单位区间。 第二种那就是在建树的时候改变通常策略,1 ~ 10 为总区间,两个孩子为1 ~ 5 ,5 ~
10。
核心难点:当我们每次找到需要更新的区间,首先应该更新cover值,然后判断此时是被覆盖了,还是解除覆盖了,如果刚好被覆盖,那么此结点的sum值也就为结点真实区间值。如果是刚好解除覆盖,那么需要看看是否有他的孩子是被覆盖的,如果有,那么应该把两孩子值加到父亲sum上。
回溯时要判断每个子树根节点是否被覆盖,如果被覆盖那么就用当前父节点的值继续参与往上递归,如果未覆盖父节点就应该把孩子值更新上来,然后继续参与往上递归。 就会发现如果从根节点往下看,能够看到的第一层被覆盖的结点所表示的区间组合起来恰好就是总区间的sum值。
Atlantis
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8948 Accepted Submission(s): 3833
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
Source
Mid-Central European Regional Contest 2000
version 1:
/*============================================================================= # # Author: liangshu - cbam # # QQ : 756029571 # # School : 哈尔滨理工大学 # # Last modified: 2015-08-11 12:30 # # Filename: A.cpp # # Description: # The people who are crazy enough to think they can change the world, are the ones who do ! =============================================================================*/ # #include<iostream> #include<sstream> #include<algorithm> #include<cstdio> #include<string.h> #include<cctype> #include<string> #include<cmath> #include<vector> #include<stack> #include<queue> #include<map> #include<set> using namespace std; const int INF = 2024; struct line { double s, e, y, mark; line(double s, double e, double y, double ma):s(s),e(e),y(y), mark(ma){} bool friend operator < (line a, line b){ return a.y < b.y; } }; struct Tree{ int cover; int lft,rht;double sum; }tree[INF<<2]; vector<double>X; vector<line>L; map<double, int>h; void create(int root, int left, int right){ tree[root].lft = left; tree[root].rht = right; tree[root].sum = 0; if(left + 1 != right){ int mid = (left + right)/2; create(root<<1, left, mid); create(root<<1|1, mid, right); } return ; } void update(int root, int val, int left, int right){ if(tree[root].lft >= left && tree[root].rht <= right){ tree[root].cover += val; if(tree[root].cover){ tree[root].sum = X[tree[root].rht] - X[tree[root].lft];return ; } else{ tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum; return ; } } if(tree[root].lft == tree[root].rht)return ; int mid = (tree[root].lft + tree[root].rht)/2; if(left < mid){ update(root <<1, val, left, right); } if(right >= mid){ update(root<<1|1,val,left, right); } if(!tree[root].cover) tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum; } int main(){ int n,cs = 1; while(~scanf("%d", &n)&&n){ h.clear();L.clear();X.clear(); double x1, y1, x2, y2; for(int i = 1; i <= n; i++){ scanf("%lf%lf%lf%lf",&x1, &y1, &x2, &y2); L.push_back(line(x1, x2, y1, 1)); L.push_back(line(x1, x2, y2, -1)); X.push_back(x1);X.push_back(x2); } sort(X.begin(), X.end()); sort(L.begin(), L.end()); X.erase(unique(X.begin(),X.end()), X.end()); for(int i = 0; i < X.size(); i++){ h[X[i]] = i; } create(1, 0, X.size() - 1); double ans = 0;int i; for( i = 0; i < L.size() - 1; i++){ update(1, L[i].mark, h[L[i].s], h[L[i].e]); ans += (L[i + 1].y - L[i].y) * tree[1].sum; } update(1, L[i].mark, h[L[i].s], h[L[i].e]); printf("Test case #%d\nTotal explored area: %.2lf\n\n",cs++ , ans); } }
version 2 :
/*============================================================================= # # Author: liangshu - cbam # # QQ : 756029571 # # School : 哈尔滨理工大学 # # Last modified: 2015-08-11 12:50 # # Filename: A.cpp # # Description: # The people who are crazy enough to think they can change the world, are the ones who do ! =============================================================================*/ # #include<iostream> #include<sstream> #include<algorithm> #include<cstdio> #include<string.h> #include<cctype> #include<string> #include<cmath> #include<vector> #include<stack> #include<queue> #include<map> #include<set> using namespace std; const int INF = 2222; struct line { double s, e, y, mark; } L[INF]; double sum[INF<<2]; int cnt[INF<<2]; vector<double>dict; bool cmp(line a, line b) { return a.y < b.y; } void pushup(int rt, int l, int r) { if(cnt[rt]) { sum [rt] = dict[r + 1] - dict[l] ; } else sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } int bin(double k, int len) { int l = 0, r = len - 1; while (l <= r) { int mid = (l + r)>>1; if(dict[mid] == k)return mid; else if(dict[mid] > k)r = mid - 1; else l = mid + 1; } return -1; } void update(int rt, int L, int R, int l ,int r, int val) { if(L <= l && r <= R) { cnt[rt] += val; pushup(rt, l, r); return ; } int mid = (l + r)>>1; if(L <= mid)update(rt<<1, L, R, l , mid, val); if(R > mid)update(rt<<1|1,L, R, mid + 1, r, val); pushup(rt,l, r); } int main() { int n,cs = 1; while(scanf("%d", &n) != EOF && n) { memset(sum, 0, sizeof(sum)); int t = 0; for(int i = 1; i <= n; i++) { double x1,y1,x2,y2; scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2); dict.push_back (x1); L[t].s = x1; L[t].e = x2; L[t].y = y1; L[t++].mark = 1; dict.push_back(x2); L[t].s = x1; L[t].e = x2; L[t].y = y2; L[t++].mark = -1 ; } sort(L , L + t, cmp); sort(dict .begin(), dict.end()); dict.erase (unique(dict.begin(), dict.end()), dict.end()); double ans = 0; for(int i = 0; i < t ; i ++ ) { int l = bin(L[i].s, dict.size()); int r = bin(L[i].e, dict.size()) - 1; if(l <= r) update(1, l, r, 0, dict.size() - 1, L[i].mark); ans += sum[1] * (L[i + 1].y - L[i].y); } printf("Test case #%d\nTotal explored area: %.2lf\n\n",cs++ , ans); } return 0 ; }
相关文章推荐
- 怎么把一篇pdf转换成html
- Android javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
- 在Python Web项目中使用Jenkins进行持续集成
- awk
- 积跬步,聚小流------Bootstrap学习记录(3)
- 基于zend Framework 的购物车系统的实现
- java正则去掉小数点后多余0
- 学习jenkins持续集成
- 快速傅里叶变换(FFT)的原理及公式
- [leetcode-104]Maximum Depth of Binary Tree(c)
- linux 下配置vncserver
- chrome 安装报错问题
- recvfrom WSAEFAULT 10014 的错误记录
- 【Xamarin开发 Android 系列 6】 Android 结构基础(上)
- Algorithms—113.Path Sum II
- HDU 2577(How to Type)动态规划
- 如何在网站中添加百度地图
- JavaScript设置表单上传时文件个数的方法
- iOS 微信支付的那些事
- 布局方案的选择