zoukankan      html  css  js  c++  java
  • hdu 1542 线段树扫描(面积)

    Atlantis

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


    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 
    /*
    hdu 1542 线段树扫描(面积)
    
    
    给你n个矩形,求最终形成的图形的面积大小
    
    
    数据不一定是整数,所以先对他们进行离散化处理
    大致就是每次计算平行于x轴的两条相邻线之间的面积,我们已经知道了两条平行
    线之间的高度,于是就转变成在求当前情况下映射到x轴上的线段的长度,这个便能
    利用线段树解决了
    
    
    先把所有平行于x轴的线段按高度排序,然后从下往上,每次在遇到矩形下边时在
    [l,r]上加1表示线段覆盖,遇到上边则填上-1消除影响.然后每次计算覆盖长度
    再乘上高即可
    
    
    参考(图文详解):
    http://www.cnblogs.com/scau20110726/archive/2013/04/12/3016765.html
    
    
    hhh-2016-03-26 17:58:50
    */
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define lson  (i<<1)
    #define rson  ((i<<1)|1)
    typedef long long ll;
    const int maxn = 10005;
    double hs[maxn];
    struct node
    {
        int l,r;
        double len;
        int sum;
        int mid()
        {
            return (l+r)>>1;
        }
    } tree[maxn*5];
    
    
    void push_up(int i)
    {
        if(tree[i].sum)
        {
            tree[i].len = (hs[tree[i].r+1]-hs[tree[i].l]);
        }
        else if(tree[i].l == tree[i].r)
        {
            tree[i].len= 0;
        }
        else
        {
            tree[i].len = tree[lson].len+tree[rson].len;
        }
    }
    
    
    void build(int i,int l,int r)
    {
        tree[i].l = l;
        tree[i].r = r;
        tree[i].sum = tree[i].len = 0;
        if(l == r)
            return ;
    
    
        int mid = tree[i].mid();
        build(lson,l,mid);
        build(rson,mid+1,r);
        push_up(i);
    }
    
    
    void push_down(int i)
    {
    
    
    }
    
    
    void Insert(int i,int l,int r,int val)
    {
        if(tree[i].l >= l && tree[i].r <=r )
        {
            tree[i].sum += val;
            push_up(i);
            return ;
        }
        int mid = tree[i].mid();
        push_down(i);
        if(l <= mid)
            Insert(lson,l,r,val);
        if(r > mid)
            Insert(rson,l,r,val);
        push_up(i);
    }
    
    
    struct edge
    {
        double l,r,high;
        int va;
        edge() {};
        edge(double _l,double _r,double _high,int _va):l(_l),r(_r),high(_high),va(_va)
        {}
    };
    edge tx[maxn*2];
    
    
    bool cmp(edge a,edge b)
    {
        if(a.high != b.high)
            return a.high < b.high;
        else
            return a.va > b.va;
    }
    int tot,m;
    int fin(double x)
    {
        int l = 0,r = m-1;
        while(l <= r)
        {
            int mid = (l+r)>>1;
            if(hs[mid] == x)
                return mid;
            else if(hs[mid] < x)
                l = mid+1;
            else
                r = mid-1;
        }
    }
    
    
    int main()
    {
        int n;
        int cas =1;
        while(scanf("%d",&n) != EOF && n)
        {
            double x1,x2,y1,y2;
            tot = 0;
            for(int i = 1; i <= n; i++)
            {
                scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
                hs[tot] = x1;
                tx[tot++] = edge(x1,x2,y1,1);
                hs[tot] = x2;
                tx[tot++] = edge(x1,x2,y2,-1);
            }
            sort(tx,tx+tot,cmp);
            sort(hs,hs+tot);
            m = 1;
            for(int i = 1;i < tot;i++)
            {
                if(hs[i] != hs[i-1])
                    hs[m++] = hs[i];
            }
            build(1,0,m);
            double ans = 0;
            for(int i = 0;i < tot;i++)
            {
                int l = fin(tx[i].l);
                int r = fin(tx[i].r)-1;
    
    
                Insert(1,l,r,tx[i].va);
                ans += (tree[1].len)*(tx[i+1].high-tx[i].high);
                //cout << ans <<endl;
            }
            printf("Test case #%d
    ",cas++);
            printf("Total explored area: %.2f
    
    ",ans);
        }
        return 0;
    }
    

      

    
    
  • 相关阅读:
    gitblit.cmd运行自动关闭
    用SourceTree轻松Git项目图解
    GUI for git|SourceTree|入门基础
    SourceTree的简单使用
    Windows平台使用Gitblit搭建Git服务器图文教程
    使用Gitblit 搭建Windows Git服务器
    Git使用详细教程
    Kafka 设计与原理详解
    Kafka 客户端实现逻辑分析
    js判断只能输入数字或小数点
  • 原文地址:https://www.cnblogs.com/Przz/p/5409587.html
Copyright © 2011-2022 走看看