zoukankan      html  css  js  c++  java
  • [codevs3044]矩形面积求并

    题目描述 Description
    输入n个矩形,求他们总共占地面积(也就是求一下面积的并)
    输入描述 Input Description

    可能有多组数据,读到n=0为止(不超过15组)

    每组数据第一行一个数n,表示矩形个数(n<=100)

    接下来n行每行4个实数x1,y1,x2,y1(0 <= x1 < x2 <= 100000;0 <= y1 < y2 <= 100000),表示矩形的左下角坐标和右上角坐标

    输出描述 Output Description
    每组数据输出一行表示答案
    样例输入 Sample Input
    2
    10 10 20 20
    15 15 25 25.5
    0
    样例输出 Sample Output
    180.00
    数据范围及提示 Data Size & Hint
     无

     矩形面积并,扫描线+线段树

    本题的线段树比较奇怪
    其中的坑点在pushup,线段树维护的区间[l,r]如果l,r相等并不是一段空集,而是线段pos[l]-pos[r+1] 这一线段

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    #include<cstring>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> PII;
    #define mem(a,b) memset(a,b,sizeof(a))
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
        while(isdigit(c)){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    const int maxn=210;
    int n,add[maxn<<2];
    double a,b,c,d,pos[maxn],sum[maxn<<2],ans;
    struct segment
    {
        double X,x,Y;int tag;
        segment(){}
        segment(double _1,double _2,double _3,int _4):X(_1),x(_2),Y(_3),tag(_4) {}
        bool operator < (const segment &s)const {return Y<s.Y;}
    }seg[maxn];
    void pushup(int l,int r,int o)
    {
        if(add[o])sum[o]=pos[r+1]-pos[l];
        else if(l==r)sum[o]=0;
        else sum[o]=sum[o<<1]+sum[o<<1|1];
    }
    void update(int l,int r,int o,int L,int R,int c)
    {
        if(L==l && r==R)
        {
            add[o]+=c;
            pushup(l,r,o);
            return;
        }
        int mid=(l+r)>>1,lo=o<<1,ro=lo|1;
        if(R<=mid)update(l,mid,lo,L,R,c);
        else if(L>mid)update(mid+1,r,ro,L,R,c);
        else update(l,mid,lo,L,mid,c),update(mid+1,r,ro,mid+1,R,c);
        pushup(l,r,o);
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF && n)
        {
            mem(pos,0);mem(sum,0);mem(add,0);ans=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
                seg[i*2]=segment(a,c,b,1);pos[i*2]=a;
                seg[i*2-1]=segment(a,c,d,-1);pos[i*2-1]=c;
            }
            sort(seg+1,seg+n*2+1);sort(pos+1,pos+n*2+1);
            for(int i=1;i<=2*n;i++)
            {
                int l=lower_bound(pos+1,pos+n*2+1,seg[i].X)-pos;
                int r=lower_bound(pos+1,pos+n*2+1,seg[i].x)-pos-1;
                update(1,2*n,1,l,r,seg[i].tag);
                ans+=sum[1]*(seg[i+1].Y-seg[i].Y);
            }
            printf("%.2lf
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    hdu 1443 Joseph 约瑟夫环
    hdu 1568 Fibonacci 对数。。
    UILineBreakMode
    Android RelativeLayout 动态添加组件
    iOS 让view触发点击事件
    读取plist文件数据
    [转]Android获取SD卡视频音频文件
    ubuntu下vim修复
    DMO(DirectX Media Object)的工程创建过程及其调用方式
    《Windows程序设计》笔记 —— Chapter One
  • 原文地址:https://www.cnblogs.com/FYH-SSGSS/p/6923145.html
Copyright © 2011-2022 走看看