标签:time second source file turn 设置 return targe script
题目链接: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 }
题目:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 23249 | Accepted: 8669 |
Description
Input
Output
Sample Input
2 10 10 20 20 15 15 25 25.5 0
Sample Output
Test case #1 Total explored area: 180.00
Source
标签:time second source file turn 设置 return targe script
原文地址:http://www.cnblogs.com/bolderic/p/7323268.html