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;
}

  

原文地址:https://www.cnblogs.com/liulangye/p/2617249.html