• HDU 1255 覆盖的面积(矩形面积交)


    覆盖的面积

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


    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
     
    Recommend
    Ignatius.L
     
     
     
     
    矩形面积交。线段树的经典题了,重新做了一遍。
    /*
    HDU 1255 覆盖的面积
    求矩形面积交(离散化+线段树)
    给定一些矩形
    求被这些矩形覆盖过至少两次的区域的面积
    
    Author:kuangbin
    date:2012-8-15
    
    */
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<iostream>
    using namespace std;
    const int MAXN=2020;
    struct Node
    {
        int l,r;
        int c;
        double lf,rf;
        double cnt;//覆盖一次以上的长度
        double more;//覆盖两次以上的长度
    }segTree[MAXN*3];
    struct Line
    {
        double x,y1,y2;
        double f;
    }line[MAXN];
    
    double y[MAXN];
    
    bool cmp(Line a,Line b)
    {
        return a.x<b.x;
    }
    
    void Build(int i,int l,int r)
    {
        segTree[i].l=l;
        segTree[i].r=r;
        segTree[i].cnt=0;
        segTree[i].more=0;
        segTree[i].lf=y[l];
        segTree[i].rf=y[r];
        if(l+1==r)return;
        int mid=(l+r)>>1;
        Build(i<<1,l,mid);
        Build((i<<1)|1,mid,r);
    }
    void calen(int i)
    {
        if(segTree[i].c>=2)
        {
            segTree[i].more=segTree[i].cnt=segTree[i].rf-segTree[i].lf;
            return;
        }
        else if(segTree[i].c==1)
        {
            segTree[i].cnt=segTree[i].rf-segTree[i].lf;
            if(segTree[i].l+1==segTree[i].r)segTree[i].more=0;
            else segTree[i].more=segTree[i<<1].cnt+segTree[(i<<1)|1].cnt;
        }
        else
        {
            if(segTree[i].l+1==segTree[i].r)
            {
                segTree[i].cnt=segTree[i].more=0;
            }
            else
            {
                segTree[i].cnt=segTree[i<<1].cnt+segTree[(i<<1)|1].cnt;
                segTree[i].more=segTree[i<<1].more+segTree[(i<<1)|1].more;
            }
        }
    }
    void update(int i,Line e)
    {
        if(e.y1==segTree[i].lf&&segTree[i].rf==e.y2)
        {
            segTree[i].c+=e.f;
            calen(i);
            return;
        }
        if(e.y2<=segTree[i<<1].rf) update(i<<1,e);
        else if(e.y1>=segTree[(i<<1)|1].lf) update((i<<1)|1,e);
        else
        {
            Line temp=e;
            temp.y2=segTree[i<<1].rf;
            update(i<<1,temp);
            temp=e;
            temp.y1=segTree[(i<<1)|1].lf;
            update((i<<1)|1,temp);
        }
        calen(i);
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        int T;
        int n;
        double x1,y1,x2,y2;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            int t=1;
            for(int i=1;i<=n;i++)
            {
                scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
                line[t].x=x1;
                //这里题目描述有问题?左下角和右上角
                line[t].y1=y1;
                line[t].y2=y2;
                line[t].x=x1;
                line[t].f=1;
                y[t]=y1;
                t++;
                line[t].y1=y1;
                line[t].y2=y2;
                line[t].x=x2;
                line[t].f=-1;
                y[t]=y2;
                t++;
            }
            sort(line+1,line+t,cmp);
            sort(y+1,y+t);
            Build(1,1,t-1);
            update(1,line[1]);
            double ans=0;
            for(int i=2;i<t;i++)
            {
                ans+=segTree[1].more*(line[i].x-line[i-1].x);
                update(1,line[i]);
            }
            printf("%.2lf\n",ans);
        }
        return 0;
    }
  • 相关阅读:
    hbase深入了解
    Android SDK安装与环境变量配置以及开发第一个Android程序
    Android平台架构及特性
    android Notification定义与应用
    Windows Phone 7 开发 31 日谈——第1日:项目模板
    MVC HtmlHelper类的方法总结(转)
    INotifyPropertyChanged的使用
    浅谈计算机软件的破解与保护(时间:20111224作者:李富云 来源:中国论文库)
    托管代码&非托管代码
    .net也疯狂:生成zip文件(转)
  • 原文地址:https://www.cnblogs.com/kuangbin/p/2640865.html
Copyright © 2020-2023  润新知