poj 1151 Atlantis

http://poj.org/problem?id=1151

几何面积并 离散化

线段树  

#include<iostream>

#include<cstdio>

#include<cstdlib>

#include<ctime>

#include<queue>

#include<cstring>

#include<set>

#include<cmath>

#include<algorithm>

#define LL long long



using namespace std;



const int N=105;

struct node

{

    int l,r;

    double lf,rf,width;

    int cover;

}mem[N*6];//线段树 lf rf 分别为边界 cover 为覆盖情况 width 为覆盖8宽度

struct poin

{

    double x;

    double y1,y2;

    int k;

}point[N*2];//拆点 k为-1代表左点 1 代表右点

double Y[N*2];

bool cmp(poin a,poin b)

{

    return a.x<b.x;

}

void build(int x,int l,int r)//建树

{

    mem[x].l=l;

    mem[x].r=r;

    mem[x].lf=Y[l];

    mem[x].rf=Y[r];

    mem[x].cover=mem[x].width=0;

    if(l+1==r)

    return ;

    int mid=(l+r)>>1;

    build(x*2,l,mid);

    build(x*2+1,mid,r);

}

void find(int x)//更新此处的覆盖宽度

{

    if(mem[x].cover>0)

    {

        mem[x].width=mem[x].rf-mem[x].lf;

        return ;

    }

    if(mem[x].l+1==mem[x].r)

    mem[x].width=0;

    else

    mem[x].width=mem[x*2].width+mem[x*2+1].width;

}

void add(int x,int k)//加入一个点的影响

{

    if(mem[x].lf>=point[k].y1&&mem[x].rf<=point[k].y2)//全部覆盖

    {

        mem[x].cover+=point[k].k;

        find(x);

        return ;

    }

    int mid=(mem[x].l+mem[x].r)>>1;

    if(Y[mid]<=point[k].y1)//查看 需要怎样往下更新

    {

        add(x*2+1,k);

    }else if(Y[mid]>=point[k].y2)

    {

        add(x*2,k);

    }else

    {

        add(x*2,k);

        add(x*2+1,k);

    }

    find(x);

}

int main()

{

    //freopen("data.txt","r",stdin);

    int n;

    int T=0;

    while(scanf("%d",&n)!=EOF)

    {

        if(n==0)

        break;

        ++T;

        double x1,y1,x2,y2;

        int I=0;

        for(int i=1;i<=n;++i)

        {

            scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);

            point[I].x=x1;

            point[I].y1=y1;

            point[I].y2=y2;

            point[I].k=1;

            Y[I]=y1;

            ++I;

            point[I].x=x2;

            point[I].y1=y1;

            point[I].y2=y2;

            point[I].k=-1;

            Y[I]=y2;

            ++I;

        }

        sort(Y,Y+I);

        sort(point,point+I,cmp);

        build(1,0,I-1);

        add(1,0);

        double ans=0;

        for(int i=1;i<I;++i)

        {

            //cout<<i<<endl;

            ans+=(mem[1].width*(point[i].x-point[i-1].x));//每次用两个x坐标差 ×   当前覆盖宽度

            //cout<<ans<<endl;

            add(1,i);//cout<<"TTT"<<endl;

        }

        printf("Test case #%d\n",T);

        printf("Total explored area: %.2f\n\n",ans);

    }

    return 0;

}

  

你可能感兴趣的:(ant)