zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    USACO 3.3 A Game
    USACO 3.3 Camelot
    USACO 3.3 Shopping Offers
    USACO 3.3 TEXT Eulerian Tour中的Cows on Parade一点理解
    USACO 3.3 Riding the Fences
    USACO 3.2 Magic Squares
    USACO 3.2 Stringsobits
    USACO 3.2 Factorials
    USACO 3.2 Contact
    USACO 3.1 Humble Numbers
  • 原文地址:https://www.cnblogs.com/liulangye/p/2617249.html
Copyright © 2011-2022 走看看