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

      

  • 相关阅读:
    STL: merge
    STL: rotate
    javascript的prototype继承问题
    日期正则表达式
    有关linq的一系列学习的文章,值得收藏
    EF读取关联数据
    jQuery UI中的日期选择插件Datepicker
    LINQ的基本语法中八个关键字用法说明
    Shell变量内容的删除、替代与替换
    Shell命令别名与历史命令
  • 原文地址:https://www.cnblogs.com/liulangye/p/2617249.html
Copyright © 2011-2022 走看看