//考察:线段树+离散化+扫描线 //PE 一次,最后还要再输出一个空行 #include<iostream> #include<algorithm> using namespace std; struct seg{ double x,y1,y2; int flag;//加入矩形最开始那条边为+1,加入矩形对边的时候为-1 seg(double a,double b,double c,int d):x(a),y1(b),y2(c),flag(d){} seg(){}; }; seg line[205]; int cmp(seg a,seg b){ return a.x<b.x; } struct Node{ int l,r; double yl,yr; //cover这个变量很有用,每当加入矩形的一条对边时候,实际上是将该线段抹掉了 //所以只有当cover>0的时候,才能说明该段线段被覆盖了 int cover; Node(int a,int b,double l,double r,int cv,double len):l(a),r(b),yl(l),yr(r),cover(cv){} Node(){} }; Node tree[205*4]; double y[205]; void build(int root,int l,int r){ //y的用途在这儿 tree[root]=Node(l,r,y[l],y[r],0); int mid=(l+r)>>1; if(l+1==r) return; build(root*2,l,mid); build(root*2+1,mid,r); } //插入线段,注意flag的修改 void insert(int root,seg b){ if(b.y2<=tree[root].yl||b.y1>=tree[root].yr) return; if(b.y1<=tree[root].yl&&b.y2>=tree[root].yr){ tree[root].cover+=b.flag; return; } insert(root*2,b); insert(root*2+1,b); } double ss; void Count(int root){ if(tree[root].cover>0){ ss+=(tree[root].yr-tree[root].yl); return; } if(tree[root].r-tree[root].l==1) return; Count(root*2); Count(root*2+1); } int n; double x1,x2,y1,y2; int main(){ int cases=0; while(scanf("%d",&n)!=EOF&&n){ cases++; int m=0; while(n--){ scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); line[++m]=seg(x1,y1,y2,1);y[m]=y1; line[++m]=seg(x2,y1,y2,-1);y[m]=y2; } //离散化 sort(line+1,line+1+m,cmp);sort(y+1,y+1+m); build(1,1,m); double sum=0; for(int i=1;i<m;i++){ insert(1,line[i]); ss=0; Count(1); sum+=ss*(line[i+1].x-line[i].x); } printf("Test case #%d\n",cases); printf("Total explored area: %.2lf\n",sum); printf("\n"); } return 0; }