hdu 1542(线段树 求矩形面积并)Atlantis

来源:互联网 发布:淘宝充300抢150的攻略 编辑:程序博客网 时间:2024/05/16 08:44

终于A了。哈哈!!

思路大概就是把:所有的矩形分成横线,竖线。按照y轴排序,那么,此时就有了y轴所有横线的区间。就可以用线段树把所有区间分啊分的。。。

画个图,把一个矩形的左边标记为1,右边标记为-1。用cover值来表示一个区间是否有竖线覆盖。

很容易知道,当cover值是大于0的时候,那么有竖线覆盖此区间。

这时,只需要知道覆盖这段区间的x坐标的值,就可以求出面积了。

然后,更新这段区间的cover值,x坐标的值。


#include <iostream>#include<cstring>#include<algorithm>using namespace std;double sgTree[205<<2];  //区间面积double y[205];double x[205<<2];      //区间相邻左边的x值int cover[205<<2];     //区间的覆盖值,即此区间有几条竖线还仍然在struct Line{double x;double y_down,y_up;int side;}line[205];      //Line表示竖线的x值与它的y值区间int cmp(Line a,Line b){return a.x<b.x;}void build(){memset(sgTree,0,sizeof(sgTree));memset(cover,0,sizeof(cover));memset(x,0,sizeof(x));}void update(int l,int r,int rt,Line a){if(l+1==r){if(cover[rt]>0)   //如果,该区间有竖线覆盖,那么计算面积。sgTree[rt]+=(y[r]-y[l])*(a.x-x[rt]);cover[rt]+=a.side;    //更新该区间的覆盖值与x坐标x[rt]=a.x;return;}int mid=(l+r)/2;if(a.y_up<=y[mid]) update(l,mid,rt*2,a);else if(a.y_down>=y[mid]) update(mid,r,rt*2+1,a);else{Line b;     //把要求的区间分成两段b.x=a.x;b.y_down=a.y_down;b.y_up=y[mid];b.side=a.side;update(l,mid,rt*2,b);b.y_down=y[mid];b.y_up=a.y_up;update(mid,r,rt*2+1,b);}sgTree[rt]=sgTree[rt*2]+sgTree[rt*2+1];}int main(){int n;int t=1;while(scanf("%d",&n)==1&&n){int k=1;while(n--){double a,b,c,d;scanf("%lf %lf %lf %lf",&a,&b,&c,&d);line[k].x=a;line[k].y_down=b;line[k].y_up=d;line[k].side=1;y[k++]=b;line[k].x=c;line[k].y_down=b;line[k].y_up=d;line[k].side=-1;y[k++]=d;}sort(y+1,y+k);    //把所有横线排序sort(line+1,line+k,cmp);   //把所有竖线排序build();     //初始化for(int i=1;i<k;i++)update(1,k,1,line[i]);printf("Test case #%d\nTotal explored area: %.2lf\n\n",t++,sgTree[1]);}return 0;}


原创粉丝点击