求矩形面积并。。扫描线第一题。把x坐标离散化,y坐标排序,从低到高一条一条线段处理,每次得到前一段面积。
#include <iostream> #include <cstring> #include <cstdio> #include <queue> #include <algorithm> #include <stdlib.h> #include <math.h> #include <stack> using namespace std; int n; struct Seg{ double xl,xr; double y; int flag; Seg(){ } Seg(double xl,double xr,double y,int flag):xl(xl),xr(xr),y(y),flag(flag){} bool operator<(const Seg& other)const{ return y<other.y; } }; double X[210]; Seg seg[210]; const double eps = 1e-8; bool equal(double a,double b){ if(fabs(a-b)<eps)return 1; return 0; } int bs(double d,int L,int R){ while(L<=R){ int mid = (L+R)>>1; if(equal(X[mid],d))return mid; if(X[mid]<d){ L=mid+1; }else{ R=mid-1; } } return -1; } struct node{ int l,r; int cnt; double width; }tree[810]; void build_tree(int n,int l,int r){ tree[n].l=l; tree[n].r=r; tree[n].cnt=0; tree[n].width=0.0; if(l==r)return; int mid=(l+r)>>1; build_tree(n<<1,l,mid); build_tree((n<<1)|1,mid+1,r); } void push_up(int n){ if(tree[n].cnt){ tree[n].width=X[tree[n].r+1]-X[tree[n].l]; }else{ tree[n].width=0; } if(tree[n].l<tree[n].r)tree[n].width=max(tree[n<<1].width+tree[(n<<1)|1].width,tree[n].width); } void update(int n,int l,int r,int val){ if(tree[n].l==l&&tree[n].r==r){ tree[n].cnt+=val; push_up(n); return; } int mid = (tree[n].l+tree[n].r)>>1; if(mid>=r){ update(n<<1,l,r,val); }else{ if(mid<l){ update((n<<1)|1,l,r,val); }else{ update(n<<1,l,mid,val); update((n<<1)|1,mid+1,r,val); } } push_up(n); } int main(){ int cas=0; while(cin>>n){ cas++; if(!n)break; int m=0; for(int i=0;i<n;i++){ double x1,y1,x2,y2; scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); X[m]=x1; seg[m++]=Seg(x1,x2,y1,1); X[m]=x2; seg[m++]=Seg(x1,x2,y2,-1); } sort(X,X+m); sort(seg,seg+m); int k = unique(X,X+m)-X; double re=0.0; build_tree(1,0,k-1); for(int i=0;i<m;i++){ double curWidth = tree[1].width; if(i){ re+=curWidth*(seg[i].y-seg[i-1].y); } int l = bs(seg[i].xl,0,k-1); int r = bs(seg[i].xr,0,k-1); update(1,l,r-1,seg[i].flag); } printf("Test case #%d\n",cas); printf("Total explored area: %.2f\n\n",re); } return 0; }