zoukankan      html  css  js  c++  java
  • Atlantis

    Atlantis

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 11532    Accepted Submission(s): 4898


    Problem Description
    There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps describe different regions of Atlantis. Your friend Bill has to know the total area for which maps exist. You (unwisely) volunteered to write a program that calculates this quantity.
     
    Input
    The input file consists of several test cases. Each test case starts with a line containing a single integer n (1<=n<=100) of available maps. The n following lines describe one map each. Each of these lines contains four numbers x1;y1;x2;y2 (0<=x1<x2<=100000;0<=y1<y2<=100000), not necessarily integers. The values (x1; y1) and (x2;y2) are the coordinates of the top-left resp. bottom-right corner of the mapped area.

    The input file is terminated by a line containing a single 0. Don’t process it.
     
    Output
    For each test case, your program should output one section. The first line of each section must be “Test case #k”, where k is the number of the test case (starting with 1). The second one must be “Total explored area: a”, where a is the total explored area (i.e. the area of the union of all rectangles in this test case), printed exact to two digits to the right of the decimal point.

    Output a blank line after each test case.
     
    Sample Input
    2 10 10 20 20 15 15 25 25.5 0
     
    Sample Output
    Test case #1 Total explored area: 180.00
     
    Source
     
    Recommend
    linle   |   We have carefully selected several similar problems for you:  1828 1255 1540 1394 1823 
       
    #include<bits/stdc++.h>
    using namespace std;
    /******************************线段树扫描线模板**********************************/
    #define N 400010
    #define lson i*2,l,m
    #define rson i*2+1,m+1,r
    
    double X1,X2,Y1,Y2;
    double X[N];//用来离散化坐标的
    int n;
    int res1=0;//表示矩形的个数
    int res2=0;//表示横坐标的个数
    double cur=0;
    int k=1;//表示不重复点横坐标的个数
    
    struct Line{
        double l,r,h;
        int d;
        Line(){}
        Line(double a,double b,double c,int z):l(a),r(b),h(c),d(z){}
        bool operator < (const Line & other) const {
            return h<other.h;
        }
    };
    Line fr[N];
    double sum[N*4];//用来存储每个节点覆盖在的长度
    int cover[N*4];//>=0时表示本节点控制的区域内下位边个数-上位边个数的结果.如果==-1时,表示本节点左右子树的上下位边数不一致
    void PushUp(int i,int l,int r){//向上更新
        //先更新节点覆盖信息
        if(cover[i*2]==-1||cover[i*2]==-1){//只要有一个儿子没有别完全覆盖,这棵子树就没有被完全覆盖
            cover[i]=-1;
        }else if(cover[i*2]!=cover[i*2+1]){//如果两个儿子不相同,肯定这个子树是没有被完全覆盖的
            cover[i]=-1;
        }else 
            cover[i]=cover[i*2];
        //然后更新节点信息
        sum[i]=sum[i*2]+sum[i*2+1];
    }
    void PushDown(int i,int l,int r){//向下更新
        int m=(l+r)>>1;
        if(cover[i]!=-1){//这棵树上的所有子树的正负边数相同
            cover[i*2]=cover[i*2+1]=cover[i];//将节点信息
            sum[i*2]=( cover[i*2]?(X[m+1]-X[l]):0 );//等0的直接不用更新了
            sum[i*2+1]=( cover[i*2+1]?(X[r+1]-X[m+1]):0 );//等0的直接不用更新了
        }
    }
    void build(int i,int l,int r){
        if(l==r){
            sum[i]=0.0;
            cover[i]=0;
            return;
        } 
        int m=(l+r)>>1;
        build(lson);
        build(rson);
        PushUp(i,l,r);
    }
    void update(int ql,int qr,int v,int i,int l,int r){
        // cout<<"l="<<l<<" r="<<r<<endl;
        if(ql<=l &&r<=qr){
            if(cover[i]!=-1){
                cover[i]+=v;
                sum[i]=(cover[i]?(X[r+1]-X[l]):0);
                return;
            }
        }
        PushDown(i,l,r);
        int m=(l+r)>>1;
        if(ql<=m) update(ql,qr,v,lson);
        if(m<qr) update(ql,qr,v,rson);
    
        PushUp(i,l,r);
    }
    int findx(double key,double a[],int n){//查找这个数值在数组中的坐标
        int l=1,r=n;
        while(r>=l){
            int m=(l+r)>>1;
            if(a[m]==key)
                return m;
            else if(a[m]>key)
                r=m-1;
            else
                l=m+1;
        }
        return -1;
    }
    void init(){//初始化函数
        res1=0;
        res2=0;
        cur=0;
        k=1;
    }
    /******************************线段树扫描线模板**********************************/
    int main(){
        // freopen("in","r",stdin);
        int kase=0;
        while(scanf("%d",&n)!=EOF&&n){
            init();
            for(int i=1;i<=n;i++){
                scanf("%lf%lf%lf%lf",&X1,&Y1,&X2,&Y2);
                // cout<<X1<<" "<<y1<<" "<<X2<<" "<<Y2<<endl;
                X[++res2]=X1;
                fr[++res1]=Line(X1,X2,Y1,1);//底边
                X[++res2]=X2;
                fr[++res1]=Line(X1,X2,Y2,-1);//上边
            }
            sort(X+1,X+res2+1);//排序进行离散化
            sort(fr+1,fr+res1+1);//排序进行离散化
            for(int i=2;i<=res2;i++){//进行离散化
                if(X[i]!=X[i-1]) X[++k]=X[i];
            }
            // for(int i=1;i<=k;i++)
      //          cout<<X[i]<<" ";
      //       cout<<endl;
            // cout<<"k="<<k<<endl;
            build(1,1,k-1);//建树
            for(int i=1;i<res1;i++)
            {
                int l=findx(fr[i].l,X,k);
                int r=findx(fr[i].r,X,k)-1;
    
                if(l<=r) update(l,r,fr[i].d,1,1,k-1);
                // cout<<sum[1]<<" "<<fr[i+1].h<<" "<<fr[i].h<<endl;
                cur += sum[1]*(fr[i+1].h-fr[i].h);
            }
            printf("Test case #%d
    Total explored area: %.2lf
    
    ",++kase,cur);
        }
        return 0;
    }
  • 相关阅读:
    【Python3网络爬虫开发实战】3.1.2-处理异常
    02018_StringBuffer练习
    富文本编辑器可以如何直接复制word的图文内容到编辑器中?
    TinyMCE可以如何直接复制word的图文内容到编辑器中?
    wangEditor可以如何直接复制word的图文内容到编辑器中?
    xhEditor可以如何直接复制word的图文内容到编辑器中?
    FCKEditor可以如何直接复制word的图文内容到编辑器中?
    KindEditor可以如何直接复制word的图文内容到编辑器中?
    CKEditor可以如何直接复制word的图文内容到编辑器中?
    百度编辑器可以如何直接复制word的图文内容到编辑器中?
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/6021510.html
Copyright © 2011-2022 走看看