题意:每组数据给出正方形中点坐标及半边长,求矩形面积并;
思路:采用沿垂直方向计算矩形面积并的方法,把面积切成若干垂直条再累加。zoj上能过,但Uva688却一直RE,已经尝试过开大空间了。。。
#include#include #include #include using namespace std;const double epsi=1e-10;const int maxn=40000;struct line{ double x,y1,y2; //x坐标及上下端点y坐标 int s; line(double a=0,double b=0,double c=0,int d=0):x(a),y1(b),y2(c),s(d){} bool operator <(const line &op2) const{ return x len+child[1]->len; }public: int l,r; double len; //垂直条长度 void setup(int ll,int rr){ l=ll;r=rr; cover=0;len=0; if(ll+1==rr) return; //若区间无法二分,则返回 int mid=(l+r)/2; child[0]=new Tree(),child[1]=new Tree(); child[0]->setup(ll,mid),child[1]->setup(mid,rr);//构造左右子树 } void paint(const int &ll,const int &rr,const int &v){ //往区间为[l,r]的线段树插入边界标志为v的垂直条[ll,rr] if(ll>=r||rr<=l) return; if(ll<=l&&r<=rr){ //若[ll,rr]覆盖[l,r]则调整区间长度len if(cover+=v) len=ly[r]-ly[l]; else{ if(child[0]==NULL) len=0; else len=child[0]->len+child[1]->len; } return; } child[0]->paint(ll,rr,v),child[1]->paint(ll,rr,v);//递归左右子树 deliver();//调整覆盖区间长度 } void del(){ if(child[0]){ //若左子树存在,则递归删除左右子树 child[0]->del(); delete child[0]; child[1]->del(); delete child[1]; } }};int cas=0;int n,m,tot,ty; //l表的长度为tot,ly表的长度为tyline l[maxn<<1]; //存储垂直条double ly[maxn<<1]; //存储地图上下边的y坐标Tree *seg; //线段树指针int main(){ while(scanf("%d",&n)!=EOF){ if(n==0) break; tot=ty=0; for(int i=0;i setup(0,ty-1); for(int i=0,j;i len*(l[i].x-l[i-1].x); j=i; //依次枚举右方的垂直条,取出底边的y坐标在ly中的序号l,顶边的y坐标在ly中的序号r,左右边界标志k,将[l,r,k]插入线段树 while(j <=epsi){ seg->paint(lower_bound(ly,ly+ty,l[j].y1)-ly,lower_bound(ly,ly+ty,l[j].y2)-ly,l[j].s); ++j; } } seg->del(); delete seg; printf("%d %.2f\n",++cas,ans); } return 0;}