POJ1151-扫面线+线段树+离散化//入门题
比较水的入门题
记录矩形竖边的x坐标,离散化排序。以被标记的边建树。
扫描线段树,查询线段树内被标记的边。遇到矩形的右边就删除此边
每一段的面积是查询结果乘边的横坐标之差,求和就是答案
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 const int maxn = 1000; 7 int N,num,kase; 8 double savey[maxn*2]; 9 10 struct line{ 11 double x,y1,y2; 12 int flag; 13 bool operator < (const struct line &t) const {return x < t.x;} 14 }Line[maxn]; 15 16 struct Node{ 17 int l,r; 18 double dl,dr; 19 double len; 20 int flag; 21 }SegTree[maxn*4]; 22 23 void Build(int i,int l,int r) 24 { 25 SegTree[i].l = l; 26 SegTree[i].r = r; 27 SegTree[i].flag = SegTree[i].len = 0; 28 SegTree[i].dl = savey[l]; 29 SegTree[i].dr = savey[r]; 30 if(l +1 == r) return; 31 int mid = (l+r)>>1; 32 Build(i<<1,l,mid); 33 Build(i<<1|1,mid,r); 34 } 35 36 void getlen(int t) 37 { 38 if(SegTree[t].flag > 0) 39 { 40 SegTree[t].len = SegTree[t].dr - SegTree[t].dl; 41 return ; 42 } 43 if(SegTree[t].l+1 == SegTree[t].r) SegTree[t].len = 0; 44 else SegTree[t].len = SegTree[t<<1].len + SegTree[t<<1|1].len; 45 } 46 47 void Update(int i,line e) 48 { 49 if(e.y1 == SegTree[i].dl && e.y2 == SegTree[i].dr) 50 { 51 SegTree[i].flag += e.flag; 52 getlen(i); 53 return; 54 } 55 if(e.y2 <= SegTree[i<<1].dr) Update(i<<1,e); 56 else if(e.y1 >= SegTree[i<<1|1].dl) Update(i<<1|1,e); 57 else 58 { 59 line temp = e; 60 temp.y2 = SegTree[i<<1].dr; 61 Update(i<<1,temp); 62 temp = e; 63 temp.y1 = SegTree[i<<1|1].dl; 64 Update(i<<1|1,temp); 65 } 66 getlen(i); 67 } 68 69 int main() 70 { 71 while(~scanf("%d",&N) && N) 72 { 73 kase++; 74 num=1; 75 double x1,x2,y1,y2; 76 for(int i=1;i<=N;i++) 77 { 78 scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); 79 Line[num].x = x1; 80 Line[num].y1 = y1; 81 Line[num].y2 = y2; 82 Line[num].flag = 1; 83 savey[num++]=y1; 84 Line[num].x = x2; 85 Line[num].y1 = y1; 86 Line[num].y2 = y2; 87 Line[num].flag = -1; 88 savey[num++] = y2; 89 } 90 sort(Line+1,Line+num); 91 sort(savey+1,savey+num); 92 Build(1,1,num-1); 93 Update(1,Line[1]); 94 double ans = 0; 95 for(int i=2;i<num;i++) 96 { 97 //printf("%f %f\n",SegTree[1].len,Line[i].x-Line[i-1].x); 98 ans += SegTree[1].len * (Line[i].x - Line[i-1].x); 99 Update(1,Line[i]); 100 } 101 printf("Test case #%d\n",kase); 102 printf("Total explored area: %.2f\n\n",ans); 103 } 104 return 0; 105 }