解题思路:
先将y轴进行离散化。n个矩形的2n个横边纵坐标共构成最多2n-1个区间的边界,对这些区间编号,建立起线段树。
x轴记录左边和右边,左边时是矩形面积增加,覆盖层数增加边,右边是形面积减少,覆盖层数减少边。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 double y[210]; 6 int ncount; 7 struct line 8 { 9 double x,y1,y2; 10 bool left; 11 }; 12 line lines[210]; 13 struct node 14 { 15 int l,r; 16 node *pl,*pr; 17 double len; 18 int c; 19 }; 20 bool cmp(const line &a,const line &b) 21 { 22 return a.x<b.x; 23 } 24 node t[1010]; 25 void build(node *root,int l,int r) 26 { 27 root->l=l; 28 root->r=r; 29 root->c=0; 30 root->len=0; 31 if(l==r) return; 32 ncount++; 33 root->pl=t+ncount; 34 ncount++; 35 root->pr=t+ncount; 36 build(root->pl,l,(l+r)/2); 37 build(root->pr,(l+r)/2+1,r); 38 } 39 int searchy(int e,double x) 40 { 41 int s=0; 42 e=e-1; 43 while(s<=e) 44 { 45 int mid=s+(e-s)/2; 46 if(y[mid]==x) 47 return mid; 48 else if(y[mid]>x) 49 e=mid-1; 50 else s=mid+1; 51 } 52 return -1; 53 } 54 int mid(node *p) 55 { 56 return (p->l+p->r)/2; 57 } 58 void Insert(node *root,int l,int r) 59 { 60 if(root->l==l&&root->r==r) 61 { 62 root->len=y[r+1]-y[l]; 63 root->c++; 64 return ; 65 } 66 if(r<=mid(root)) 67 Insert(root->pl,l,r); 68 else if(l>=mid(root)+1) 69 Insert(root->pr,l,r); 70 else 71 { 72 Insert(root->pl,l,mid(root)); 73 Insert(root->pr,mid(root)+1,r); 74 } 75 if(root->c==0) 76 root->len=root->pl->len+root->pr->len; 77 } 78 void Delete(node *root,int l,int r) 79 { 80 if(root->l==l&&root->r==r) 81 { 82 root->c--; 83 if(root->c==0) 84 { 85 if(root->l==root->r) 86 root->len=0; 87 else 88 root->len=root->pl->len+root->pr->len; 89 } 90 return; 91 } 92 if(r<=mid(root)) 93 Delete(root->pl,l,r); 94 else if(l>=mid(root)+1) 95 Delete(root->pr,l,r); 96 else 97 { 98 Delete(root->pl,l,mid(root)); 99 Delete(root->pr,mid(root)+1,r); 100 } 101 if(root->c==0) 102 root->len=root->pl->len+root->pr->len; 103 } 104 int main() 105 { 106 int n; 107 double x1,x2,y1,y2; 108 int yc,lc; 109 int ca=0; 110 while(~scanf("%d",&n)&&n) 111 { 112 ca++; 113 lc=yc=0; 114 for(int i=0; i<n; i++) 115 { 116 scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); 117 y[yc++]=y1; 118 y[yc++]=y2; 119 lines[lc].x=x1; 120 lines[lc].y1=y1; 121 lines[lc].y2=y2; 122 lines[lc].left=1; 123 lc++; 124 125 lines[lc].x=x2; 126 lines[lc].y1=y1; 127 lines[lc].y2=y2; 128 lines[lc].left=0; 129 lc++; 130 } 131 sort(y,y+yc); 132 yc=unique(y,y+yc)-y; 133 build(t,0,yc-2); 134 sort(lines,lines+lc,cmp); 135 double ans=0; 136 for(int i=0; i<lc-1; i++) 137 { 138 int l=searchy(yc,lines[i].y1); 139 int r=searchy(yc,lines[i].y2)-1; 140 if(lines[i].left) 141 Insert(t,l,r); 142 else 143 Delete(t,l,r); 144 ans+=t[0].len*(lines[i+1].x-lines[i].x); 145 } 146 printf("Test case #%d ",ca); 147 printf("Total explored area: %.2f ",ans); 148 } 149 }