hdu 1542 Atlantis

来源:互联网 发布:中国网瘾少年数据最新 编辑:程序博客网 时间:2024/05/18 00:06
#include<stdio.h>#include<algorithm>using namespace std;#define Max 2005struct lnode//存放线段{double l,r,h;int d;}line[2*Max];struct node//线段树{int l,r,flag;double sum;}tree[4*Max];double X[4*Max];int k;bool cmp(lnode a,lnode b){return a.h<b.h;//从小到大}void build(int step,int l,int r){tree[step].l=l;tree[step].r=r;tree[step].flag=0;tree[step].sum=0;if(l+1==r){return;}int mid=(l+r)>>1;build(step<<1,l,mid);build(step<<1|1,mid,r);}void updata(int step,int l,int r,int c){if(l<=tree[step].l&&tree[step].r<=r){tree[step].flag+=c;if(tree[step].flag!=0){tree[step].sum=X[tree[step].r]-X[tree[step].l];//说明此线段有被覆盖}else{tree[step].sum=tree[step<<1].sum+tree[step<<1|1].sum;//还要求左右孩子是否存在覆盖,故要合并左右孩子}return ;}int mid=(tree[step].l+tree[step].r)>>1;if(mid<r){updata(step<<1|1,l,r,c);}if(l<mid){updata(step<<1,l,r,c);}if(tree[step].flag!=0){tree[step].sum=X[tree[step].r]-X[tree[step].l];//说明此线段有被覆盖}else{tree[step].sum=tree[step<<1].sum+tree[step<<1|1].sum;//合并左右孩子}}int search(double x){int low,high;int mid;low=0;high=k;while(low<=high){mid=(low+high)>>1;if(X[mid]==x){return mid;}elseif(X[mid]<x){low=mid+1;}else{high=mid-1;}}return -1;}int main(){//freopen("1.txt","r",stdin);int n,i,t=1;int m;double a,b,c,d,sum;while(scanf("%d",&n)&&n){m=0;while(n--){scanf("%lf%lf%lf%lf",&a,&b,&c,&d);//把矩形映射到X轴line[m].l=a;line[m].r=c;line[m].h=b;line[m].d=1;X[m]=a;m++;line[m].l=a;line[m].r=c;line[m].h=d;line[m].d=-1;X[m]=c;m++;}sort(X,X+m);sort(line,line+m,cmp);k=0;for(i=1;i<m;i++)//去掉重复的点{if(X[i]!=X[k]){k++;X[k]=X[i];}}build(1,0,k);sum=0;for(i=0;i<m-1;i++){int l,r;l=search(line[i].l);//寻找“线段坐标”离散化后的坐标r=search(line[i].r);if(l<r){updata(1,l,r,line[i].d);//更新线段 求矩形的长 tree[1].sum}sum+=tree[1].sum*(line[i+1].h-line[i].h);//面积=长*宽}printf("Test case #%d\n",t++);printf("Total explored area: %.2f\n\n",sum);}return 0;}

原创粉丝点击