HDU 1542

    技术2022-05-19  28

    http://acm.hdu.edu.cn/showproblem.php?pid=154220:35:22

    题目大意:求多个矩形的面积和(自己的第一个线段树求面积和~)

    #include<iostream> #include<algorithm> using namespace std; #define N 201 struct node { int l,r,cover; double len; int getmid(){ return (r+l)>>1; } }p[3*N]; struct Line { double l,r,h; int flag; }L[N]; double h[N]; double X[N]; int m; bool cmp(Line x,Line y) { return x.h<y.h; } void setlen(int id) { int l=p[id].l,r=p[id].r; if(p[id].cover>0) p[id].len=h[r]-h[l]; else { if(p[id].r-p[id].l==1) p[id].len=0; else p[id].len=p[id<<1].len+p[id<<1|1].len; } } int find(double x) { int f=0,l=m-1; int mid; while(f<=l) { mid=(f+l)>>1; if(h[mid]==x) return mid; if(h[mid]>=x) l=mid-1; else f=mid+1; } } void build(int l,int r,int id) { p[id].l=l; p[id].r=r; p[id].len=p[id].cover=0; if(r-l==1) return; int mid=p[id].getmid(); build(l,mid,id<<1); build(mid,r,id<<1|1); } void update(int l,int r,int flag,int id) { if(p[id].l==l&&p[id].r==r) { p[id].cover+=flag; setlen(id); return; } int mid=p[id].getmid(); if(r<=mid) update(l,r,flag,id<<1); else if(l>=mid) update(l,r,flag,id<<1|1); else { update(l,mid,flag,id<<1); update(mid,r,flag,id<<1|1); } setlen(id); } int main(void) { int n,k=1; while(scanf("%d",&n),n) { double x1,y1,x2,y2; m=0; while(n--) { scanf("%lf%lf",&x1,&y1); scanf("%lf%lf",&x2,&y2); X[m]=x1; L[m].l=x1; L[m].r=x2; L[m].h=y1; L[m].flag=1; m++; X[m]=x2; L[m].l=x1; L[m].r=x2; L[m].h=y2; L[m].flag=-1; m++; } sort(X,X+m); sort(L,L+m,cmp); h[0]=X[0]; int mm=m; m=1; for(int i=1;i<mm;i++) if(X[i]!=X[i-1]) h[m++]=X[i]; build(0,m-1,1); double ans=0; for(int i=0;i<mm-1;i++) { int l=find(L[i].l); int r=find(L[i].r); update(l,r,L[i].flag,1); ans+=p[1].len*(L[i+1].h-L[i].h); } printf("Test case #%d/n",k++); printf("Total explored area: %.2lf/n/n",ans); } } 

    离散化,把矩形看成一条条的平行X轴的线段,再根据Y坐标排序,h变量记录相邻两线段的距离,即高。做的时候从最底边一条条的插入就好。

    flag记录线段性质,对于同一个矩形的上下两条边,下边记为1,上边记为-1,这样就很神奇的能计算出总面积和~

     


    最新回复(0)