hdu 1542 线段树之扫描线之面积并

来源:互联网 发布:数控车编程软件 编辑:程序博客网 时间:2024/06/05 09:53

点击打开链接

题意:给你n个矩形,求它们的面积,重复的不重复计算

思路:用线段树的扫描线完成,将X坐标离散化后,从下到上扫描矩形,进行各种处理,看代码注释把

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;const int maxn=1e3+10;#define mm(a) memset(a,0,sizeof(a))int num1[maxn*4];double num[maxn*4],X[maxn*4];struct edge{    double l,r,h;    int s;//s为1是下边,s为-1是上边    edge(){};    edge(double a,double b,double c,int d) : l(a),r(b),h(c),s(d){}    bool operator<(const edge &n)const{        return h<n.h;    }}ss[maxn];void pushup(int le,int ri,int node){    if(num1[node]) num[node]=X[ri+1]-X[le];//在更新的时候,可能两个矩阵有重叠,这样就不能像以前那么更新,而是将le和ri传入    else if(le==ri) num[node]=0;           //然后将X[ri+1]-X[le]的值进行更新,避免了重复的长度    else num[node]=num[node<<1]+num[node<<1|1];}void update(int l,int r,int add,int le,int ri,int node){    if(l<=le&&ri<=r){        num1[node]+=add;//与懒惰标记类似        pushup(le,ri,node);        return ;    }    int t=(le+ri)>>1;    if(l<=t) update(l,r,add,le,t,node<<1);    if(r>t) update(l,r,add,t+1,ri,node<<1|1);    pushup(le,ri,node);}int main(){    int n,t=1;    while(scanf("%d",&n)!=-1){        if(n==0) break;        double a,b,c,d;        int k=0;        for(int i=0;i<n;i++){            scanf("%lf%lf%lf%lf",&a,&b,&c,&d);            X[k]=a;            ss[k++]=edge(a,c,b,1);            X[k]=c;            ss[k++]=edge(a,c,d,-1);        }        sort(X,X+k);        sort(ss,ss+k);        int k1=1;        for(int i=1;i<k;i++){//对X进行离散化            if(X[i]!=X[i-1]) X[k1++]=X[i];        }        mm(num);mm(num1);        double ans=0;        for(int i=0;i<k-1;i++){            int l=lower_bound(X,X+k1,ss[i].l)-X;            int r=lower_bound(X,X+k1,ss[i].r)-X-1;            update(l,r,ss[i].s,0,k1-1,1);            ans+=num[1]*(ss[i+1].h-ss[i].h);//num[1]为当前横坐标的总长度        }        printf("Test case #%d\nTotal explored area: %.2f\n\n",t++,ans);    }    return 0;}

0 0
原创粉丝点击