zoukankan      html  css  js  c++  java
  • 线段树---Atlantis

    题目网址:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=110064#problem/A

    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 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 

    题意: 给了n个矩形的左下角和右上角的坐标,求矩形面积的并(矩形可能覆盖在一起,求总面积);

    思路:使用线段树记录所有矩形上下两条边的高度,用结构体数组记录矩形的左右两条边,并按照从左往右的顺序排序,从左到右加上每一个小矩形的面积。


    代码如下:
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #define N 210
    using namespace std;
    double y[N];
    
    struct node
    {
        double x,y1,y2;
        int f;
    }Line[N];
    
    struct node1
    {
        double lf,rf,cnt;
        int l,r,c;
    }tree[N*3];
    
    int cmp1(const node a,const node b)
    {
        return a.x < b.x;
    }
    
    int cmp2(const void *a,const void *b)
    {
        return *(double *)a>*(double *)b?1:-1;
    }
    
    void bulid(int t,int l,int r)
    {
        int mid;
        tree[t].c=0; tree[t].cnt=0;
        tree[t].l=l;
        tree[t].r=r;///记录着所有矩形的两条竖边从左到右的顺序编号;
        tree[t].lf=y[l];
        tree[t].rf=y[r];
        if(l+1==r) return;
        mid=(l+r)/2;
        bulid(2*t,l,mid);
        bulid(2*t+1,mid,r);
    }
    
    void calen(int t)
    {
        if(tree[t].c>0)
        {
            tree[t].cnt=tree[t].rf-tree[t].lf;
            return ;
        }
        if(tree[t].l+1==tree[t].r) tree[t].cnt=0;///是矩形右面的边则将树节点的值清零;
        else tree[t].cnt=tree[2*t].cnt+tree[2*t+1].cnt;///计算父节点的值;
    }
    
    void updata(int t,node e)
    {
        if(e.y1 == tree[t].lf && e.y2==tree[t].rf)
        {
            tree[t].c+=e.f;
            calen(t);
            return;
        }
        if(e.y2 <=tree[2*t].rf ) updata(2*t,e);
        else if(e.y1 >=tree[2*t+1].lf) updata(2*t+1,e);
        else
        {
            node tmp=e;
            tmp.y2=tree[2*t].rf;
            updata(2*t,tmp);
            tmp=e;
            tmp.y1=tree[2*t+1].lf;
            updata(2*t+1,tmp);
        }
        calen(t);///计算各个父节点的cnt值;
    }
    
    int main()
    {
        int Case=0,n,t;
        double x1,y1,x2,y2,ans;
        while(scanf("%d",&n)!=EOF && n)
        {
            Case++;
            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].f=1;
                y[t]=y1;
    
                Line[t+1].x=x2;
                Line[t+1].y1=y1;
                Line[t+1].y2=y2;
                Line[t+1].f=-1;
                y[t+1]=y2;
                t+=2;
            }
            sort(Line+1,Line+t-1,cmp1);///对结构体Line按x值从小到大进行排序;
            qsort(y+1,t-1,sizeof(y[1]),cmp2);///对y[]数组进行从小到大的排序;
            bulid(1,1,t-1);
            ans=0;
            for(int i=1;i<t;i++)
            {
                ans+=tree[1].cnt*(Line[i].x - Line[i-1].x);
                updata(1,Line[i]);
            }
            printf("Test case #%d
    Total explored area: %.2lf
    
    ",Case,ans);
        }
        return 0;
    }
  • 相关阅读:
    标准输出stdout、标准错误stderr 分类: python python基础学习 2013-06-17 18:08 308人阅读 评论(0) 收藏
    python数据持久存储:pickle模块的基本使用 分类: python python基础学习 python 小练习 2013-06-17 14:41 209人阅读 评论(0) 收藏
    解析XML文件总结 分类: python基础学习 python 2013-06-17 12:04 232人阅读 评论(0) 收藏
    使用set()求出列表交集 分类: python基础学习 2013-06-16 17:00 241人阅读 评论(0) 收藏
    [搜索][51nod] 1268 和为K的组合
    [51nod] 1279 扔盘子
    [记忆化搜索] [洛谷] P1464 Function
    [贪心][51nod] 1133 不重叠的线段
    [二分] [51nod]1010 只包含因子2 3 5的数 lower_boud
    万年历查询 c++ 黑窗
  • 原文地址:https://www.cnblogs.com/chen9510/p/5324264.html
Copyright © 2011-2022 走看看