zoukankan      html  css  js  c++  java
  • hdu 1255

    覆盖的面积

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 5019    Accepted Submission(s): 2515

    Problem Description
    给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.


     
    Input
    输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N<=1000),代表矩形的数量,然后是N行数据,每一行包含四个浮点数,代表平面上的一个矩形的左上角坐标和右下角坐标,矩形的上下边和X轴平行,左右边和Y轴平行.坐标的范围从0到100000.

    注意:本题的输入数据较多,推荐使用scanf读入数据.
     
    Output
    对于每组测试数据,请计算出被这些矩形覆盖过至少两次的区域的面积.结果保留两位小数.
     
    Sample Input
    2 5 1 1 4 2 1 3 3 7 2 1.5 5 4.5 3.5 1.25 7.5 4 6 3 10 7 3 0 0 1 1 1 0 2 1 2 0 3 1
     
    Sample Output
    7.63 0.00
     
    Author
    Ignatius.L & weigang Lee
    呵呵,这题是在线段树求矩形面积并的基础上再进一步。segment_tree中的len表示覆盖一遍的长度,nlen表示覆盖多遍的长度。这题的重点在于写if语句判断三个要点:1)此区间已经覆盖2遍及以上;2)此区间被覆盖一次,区间是还是不是叶子节点,若不是,则有没有被覆盖两次取决于它子节点len值;3)此区间没被覆盖。
    Problem : 1255 ( 覆盖的面积 )     Judge Status : Accepted
    RunId : 17414345    Language : G++    Author : ksq2013
    Code Render Status : Rendered By HDOJ G++ Code Render Version 0.01 Beta
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    double yy[2100];
    struct Line{
        int f;
        double x,y1,y2;
        bool operator<(const Line h)const{
            return x<h.x;
        }
    }line[2100];//index:m;
    struct Seg{
        int f;
        double len,nlen;
    }tr[10100];
    void build(int s,int t,int k)
    {
        tr[k].f=tr[k].len=tr[k].nlen=0;
        if(s+1==t)return;
        int m=(s+t)>>1;
        build(s,m,k<<1);
        build(m,t,k<<1|1);
    }
    int bin(double x,int l,int r)
    {
        while(l<=r){
            int mid=(l+r)>>1;
            if(yy[mid]==x)return mid;
            if(yy[mid]<x)l=mid+1;
            else r=mid-1;
        }return l;
    }
    void pushup(int s,int t,int k)
    {
        if(tr[k].f>1)tr[k].nlen=tr[k].len=yy[t]-yy[s];
        else{
            if(tr[k].f==1){
                tr[k].len=yy[t]-yy[s];
                if(s+1==t)tr[k].nlen=0;
                else tr[k].nlen=tr[k<<1].len+tr[k<<1|1].len;
            }
            else{
                if(s+1==t)tr[k].nlen=tr[k].len=0;
                else{
                    tr[k].len=tr[k<<1].len+tr[k<<1|1].len;
                    tr[k].nlen=tr[k<<1].nlen+tr[k<<1|1].nlen;
                }
            }
        }
    }
    void update(int s,int t,int k,int l,int r,int f)
    {
        if(l<=s&&t<=r){
            tr[k].f+=f;
            pushup(s,t,k);
            return;
        }int m=(s+t)>>1;
        if(l<m)update(s,m,k<<1,l,r,f);
        if(m<r)update(m,t,k<<1|1,l,r,f);
        pushup(s,t,k);
    }
    int main()
    {
        int T,n;
        double x1,y1,x2,y2;
        scanf("%d",&T);
        for(;T;T--){
            scanf("%d",&n);
            int m=0;
            for(int i=1;i<=n;i++){
                scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
    
                yy[++m]=y1;
                line[m].f=1;//initial number:0;first variable:f;
                line[m].x=x1;
                line[m].y1=y1;
                line[m].y2=y2;
    
                yy[++m]=y2;
                line[m].f=-1;
                line[m].x=x2;
                line[m].y1=y1;
                line[m].y2=y2;
            }
            sort(1+yy,1+m+yy);//data input;
            sort(1+line,1+m+line);
            int k=1;
            for(int i=2;i<=m;i++)
                if(yy[i-1]!=yy[i])yy[++k]=yy[i];//end;
    
            double ans=0;
            build(1,k,1);//build a segment_tree;
            for(int i=1;i<=m;i++){
                update(1,k,1,bin(line[i].y1,1,k),bin(line[i].y2,1,k),line[i].f);//updating segments by binary search;
                ans+=tr[1].nlen*(line[i+1].x-line[i].x);
            }
    
            printf("%.2lf
    ",ans);//output the ans;
        }
        return 0;
    }
    

  • 相关阅读:
    Java实现 LeetCode 455 分发饼干
    Java实现 LeetCode 455 分发饼干
    Java实现 LeetCode 455 分发饼干
    Java实现 LeetCode 454 四数相加 II
    Java实现 LeetCode 454 四数相加 II
    Java实现 LeetCode 454 四数相加 II
    FFmpeg解码H264及swscale缩放详解
    linux中cat more less head tail 命令区别
    C语言字符串操作总结大全(超详细)
    如何使用eclipse进行嵌入式Linux的开发
  • 原文地址:https://www.cnblogs.com/keshuqi/p/5957785.html
Copyright © 2011-2022 走看看