POJ 1151 Atlantis 线段树+离散化
Posted EricJeffrey
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1151 Atlantis 线段树+离散化相关的知识,希望对你有一定的参考价值。
题目链接:http://poj.org/problem?id=1151 http://acm.hdu.edu.cn/showproblem.php?pid=1542
题目大意:给你几个矩形的坐标,求他们的面积的并。
解题思路:可以参考http://www.cnblogs.com/kuangbin/archive/2011/08/16/2140544.html,实际上就是一个方向直接算出,另一个方向使用线段树维护已经覆盖的底边的长度。具体操作不算复杂:假想一条扫描下从下往上开始进行扫描,初始时候没有边,线段树维护的值为0,每次碰到一条底边,就将这条底边加入线段树中并且更新他们覆盖的总长度,如果碰到顶边,就将这个边从线段树中删除,而总面积即是每两条边之间的面积的总和。
给每条底边设置个flag = 1,顶边flag = -1,那么就容易在线段树上操作了。
离散化实际上是对每个浮点数坐标离散化。注意的是离散后,线段树上的中值mid既可以在左孩子又可以在右孩子中。
代码:
1 const int maxn = 250; 2 struct node{ 3 int f; 4 double rlen, rl, rr; 5 }; 6 node tree[maxn * 4]; 7 struct Line{ 8 double x1, x2, y; 9 int flag; 10 bool operator < (const Line &t) const{ 11 return y < t.y; 12 } 13 Line() {} 14 Line(double a, double b, double c, int f): x1(a), x2(b), y(c), flag(f) {} 15 }; 16 Line lines[maxn]; 17 double ys[maxn]; 18 int n; 19 20 void build(int l, int r, int k){ 21 tree[k].f = 0; tree[k].rl = ys[l]; tree[k].rr = ys[r]; tree[k].rlen = 0; 22 if(l + 1 == r) return; 23 int mid = (l + r) >> 1, lc = k << 1, rc = k << 1 | 1; 24 build(l, mid, lc); 25 build(mid, r, rc); 26 } 27 void cacu(int l, int r, int k){ 28 if(tree[k].f > 0) { 29 tree[k].rlen = tree[k].rr - tree[k].rl; 30 return; 31 } 32 if(l + 1 == r) tree[k].rlen = 0; 33 else tree[k].rlen = tree[k << 1].rlen + tree[k << 1 | 1].rlen; 34 } 35 void update(Line ul, int l, int r, int k){ 36 if(ul.x1 <= tree[k].rl && ul.x2 >= tree[k].rr){ 37 tree[k].f += ul.flag; 38 cacu(l, r, k); 39 return; 40 } 41 if(ul.x1 > tree[k].rr || ul.x2 < tree[k].rl) return; 42 int mid = (l + r) >> 1, lc = k << 1, rc = k << 1 | 1;\\ 43 if(ul.x2 <= tree[lc].rr) update(ul, l, mid, lc); 44 else if(ul.x1 >= tree[rc].rl) update(ul, mid, r, rc); 45 else{ 46 update(ul, l, mid, lc); 47 update(ul, mid, r, rc); 48 } 49 cacu(l, r, k); 50 } 51 52 int main(){ 53 int t = 1; 54 while(scanf("%d", &n) != EOF && n != 0){ 55 int cnt = 1; 56 for(int i = 1; i <= n; i++){ 57 double x1, x2, y1, y2; 58 scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2); 59 lines[cnt] = Line(x1, x2, y1, 1); 60 ys[cnt] = x1; cnt++; 61 lines[cnt] = Line(x1, x2, y2, -1); 62 ys[cnt] = x2; cnt++; 63 } 64 sort(lines + 1, lines + cnt); 65 sort(ys + 1, ys + cnt); 66 cnt--; 67 build(1, cnt, 1); 68 update(lines[1], 1, cnt, 1); 69 double area = 0; 70 for(int i = 2; i <= cnt; i++){ 71 area += (lines[i].y - lines[i - 1].y) * tree[1].rlen; 72 update(lines[i], 1, cnt, 1); 73 } 74 printf("Test case #%d\\nTotal explored area: ", t++); 75 printf("%.2f\\n\\n", area); 76 } 77 }
题目:
Atlantis
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 23249 | Accepted: 8669 |
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 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.
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.
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
以上是关于POJ 1151 Atlantis 线段树+离散化的主要内容,如果未能解决你的问题,请参考以下文章
POJ1151Atlantis 矩形面积并[线段树 离散化 扫描线]