Poj--1151(线段树,离散化,扫描线)
2014-09-24 22:35:43
思路:经典的线段树+扫描线,由于数据较大,所以要离散化。需要注意的是建树过程中:叶子节点是长度为1的单元区间,然后相邻叶节点有重合点(思考为什么)
参考了众巨的博客,最后感觉是默了下来,看来还得再刷几道类似题才能真正懂。Orz。
1 /************************************************************************* 2 > File Name: p1151.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Wed 24 Sep 2014 09:53:10 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <queue> 14 #include <iostream> 15 #include <algorithm> 16 using namespace std; 17 typedef long long ll; 18 const int INF = 1 << 29; 19 const int maxn = 205; 20 21 struct Edge{ 22 int flag; 23 double x,y1,y2; 24 friend bool operator < (Edge a,Edge b){ 25 return a.x < b.x; 26 } 27 }e[maxn]; 28 struct node{ 29 int l,r; 30 double tl,tr,len; 31 int cover; 32 }a[maxn << 2]; 33 int n; 34 double y[maxn]; 35 36 void Build_tree(int pos,int l,int r){ 37 a[pos].l = l; 38 a[pos].r = r; 39 a[pos].tl = y[l]; 40 a[pos].tr = y[r]; 41 a[pos].cover = a[pos].len = 0; 42 if(l + 1 == r) 43 return; 44 int mid = l + (r - l) / 2; 45 Build_tree(pos << 1,l,mid); 46 Build_tree(pos << 1 | 1,mid,r); 47 } 48 49 void Cal_len(int pos){ 50 if(a[pos].cover > 0) 51 a[pos].len = a[pos].tr - a[pos].tl; 52 else if(a[pos].l + 1 == a[pos].r) 53 a[pos].len = 0; 54 else 55 a[pos].len = a[pos << 1].len + a[pos << 1 | 1].len; 56 } 57 58 void Update(int pos,int l,int r,Edge t){ 59 if(a[pos].tl == t.y1 && a[pos].tr == t.y2){ 60 a[pos].cover += t.flag; 61 Cal_len(pos); 62 return; 63 } 64 int mid = l + (r - l) / 2; 65 if(t.y2 <= a[pos << 1 | 1].tl) Update(pos << 1,l,mid,t); 66 else if(t.y1 >= a[pos << 1].tr) Update(pos << 1 | 1,mid,r,t); 67 else{ 68 Edge tmp = t; 69 tmp.y2 = a[pos << 1].tr; 70 Update(pos << 1,l,mid,tmp); 71 tmp.y2 = t.y2; 72 tmp.y1 = a[pos << 1 | 1].tl; 73 Update(pos << 1 | 1,mid,r,tmp); 74 } 75 Cal_len(pos); 76 } 77 78 int main(){ 79 int Case = 0; 80 double x1,y1,x2,y2; 81 while(scanf("%d",&n) != EOF && n){ 82 int c = 0; 83 for(int i = 1; i <= n; ++i){ 84 scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); 85 e[++c].x = x1; 86 e[c].y1 = y1; 87 e[c].y2 = y2; 88 e[c].flag = 1; 89 y[c] = y1; 90 91 e[++c].x = x2; 92 e[c].y1 = y1; 93 e[c].y2 = y2; 94 e[c].flag = -1; 95 y[c] = y2; 96 } 97 sort(e + 1,e + c + 1); 98 sort(y + 1,y + c + 1); 99 Build_tree(1,1,c); 100 Update(1,1,c,e[1]); 101 double ans = 0.0; 102 for(int i = 2; i <= c; ++i){ 103 ans += a[1].len * (e[i].x - e[i - 1].x); 104 Update(1,1,c,e[i]); 105 } 106 printf("Test case #%d\n",++Case); 107 printf("Total explored area: %.2f\n\n",ans); 108 } 109 return 0; 110 }

浙公网安备 33010602011771号