poj1151-- Atlantis(线段树+离散化+扫描线)

Atlantis

Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d
& %I64u

Submit Status

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 

写代码是为了省事,没怎么考虑就写了update中的递归,找了一下午的错,才知道那个位置写错了。。。

扫描线第二弹

题意:给出了n个矩形的左下和右上的坐标,问所有的矩形面积的并是多少

1.在建立线段树是左子树为(l,mid)右子树为(mid,r),不能是mid+1,那样会使mid+1到mid一段不被统计到

2.按x由左向右扫描,因为给出的数是实数,所以除了要离散化x点外,对于线段树中的每一段的左右区间应该更新成实数y1,y2.,通过对区间的大小比对,判断直接得到值,还是继续深入,在向下一层深入的时候,要改变要判断的区间,使得区间在节点的控制内。

3.lazy数组标记了这条线段出现的次数,如果为0时,那么该节点等于左右字数节点的和,否则就是该节点的最大值。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 300
struct node1{
    double l , r ;
    double sum ;
}cl[maxn<<3];
int lazy[maxn<<3] ;
struct node2{
    double x , y1 , y2 ;
    int flag ;
}p[maxn<<3];
double s[maxn<<3] ;
bool cmp(node2 a,node2 b)
{
    return a.x < b.x ;
}
void push_up(int rt)
{
    if( lazy[rt] > 0 )
        cl[rt].sum = cl[rt].r - cl[rt].l ;
    else
        cl[rt].sum = cl[rt*2].sum + cl[rt*2+1].sum ;
}
void creat(int rt,int l,int r)
{
    if( r - l > 1 )
    {
        cl[rt].l = s[l] ;
        cl[rt].r = s[r] ;
        creat(rt*2,l,(l+r)/2);
        creat(rt*2+1,(l+r)/2,r);
        push_up(rt);
    }
    else
    {
        cl[rt].l = s[l] ;
        cl[rt].r = s[r] ;
        cl[rt].sum = 0 ;
    }
    return ;
}
void update(int rt,double y1,double y2,int flag)
{
    if( cl[rt].l == y1 && cl[rt].r == y2 )
    {
        lazy[rt] += flag ;
        push_up(rt);
        return ;
    }
    else
    {
        if( cl[rt*2].r > y1 )
            update(rt*2,y1,min(cl[rt*2].r,y2),flag);
        if( cl[rt*2+1].l < y2 )
            update(rt*2+1,max(cl[rt*2+1].l,y1),y2,flag);
        push_up(rt);
    }
}
int main()
{
    int temp = 1 , n , i , j ;
    double x1 , y1 , x2 , y2 , ans ;
    while(scanf("%d", &n) && n)
    {
        ans = 0 ;
        for(i = 0 ; i < n ; i++)
        {
            scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2);
            p[i].x = x1 ;
            p[i].y1 = y1 ;
            p[i].y2 = y2 ;
            p[i].flag = 1 ;
            p[i+n].x = x2 ;
            p[i+n].y1 = y1 ;
            p[i+n].y2 = y2 ;
            p[i+n].flag = -1 ;
            s[i+1] = y1 ;
            s[i+n+1] = y2 ;
        }
        sort(s+1,s+(2*n+1));
        sort(p,p+2*n,cmp);
        creat(1,1,2*n);
        memset(lazy,0,sizeof(lazy));
        update(1,p[0].y1,p[0].y2,p[0].flag);
        for(i = 1 ; i < 2*n ; i++)
        {
            ans += ( p[i].x-p[i-1].x )*cl[1].sum ;
            update(1,p[i].y1,p[i].y2,p[i].flag);
        }
        printf("Test case #%d\nTotal explored area: %.2lf\n\n", temp++, ans);
    }
    return 0;
}

poj1151-- Atlantis(线段树+离散化+扫描线)

时间: 2024-08-26 17:34:52

poj1151-- Atlantis(线段树+离散化+扫描线)的相关文章

HDU 1542 Atlantis 线段树+离散化+扫描线

题意:给出一些矩形的最上角坐标和右下角坐标,求这些矩形的面积并. NotOnlySuccess 线段树专辑中扫描线模板题,弱智的我对着大大的代码看了一下午才搞懂. 具体见思路见注释=.= #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #define lson rt<<1,l,mid #define rson rt<<1|1,mid

poj3277--City Horizon(线段树+离散化+扫描线)

City Horizon Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16206   Accepted: 4414 Description Farmer John has taken his cows on a trip to the city! As the sun sets, the cows gaze at the city horizon and observe the beautiful silhouette

hdu1828 Picture(线段树+离散化+扫描线)两种方法

C - Picture Time Limit:2000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Status Description A number of rectangular posters, photographs and other pictures of the same shape are pasted on a wall. Their sides are all vertical or

POJ 2482 Stars in Your Window 线段树+离散化+扫描线

题面据说很美- 每个星星可以根据在窗口的左下角和右上角两个位置建立两条扫描线,之后就是简单的区间增减和求最大值操作了. 注意要处理在边界上的星星是不算的情况,其实只要把左右边界分别增减一个eps即可. #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <

【POJ 2482】 Stars in Your Window(线段树+离散化+扫描线)

[POJ 2482] Stars in Your Window(线段树+离散化+扫描线) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11294   Accepted: 3091 Description Fleeting time does not blur my memory of you. Can it really be 4 years since I first saw you? I still remembe

HDU 3642 线段树+离散化+扫描线

题意:给你N个长方体的左下角和右上角坐标,问你空间中有多少体积是被大于两个不同的立方体覆盖的.x,y~10^6 z~500 考虑到给的z比较小,所以可以直接枚举z,然后跑二维的扫描线就好. 关于处理被不同的线段覆盖三次的问题,可以维护四个信息,cnt,once,twice,more,然后相互推出结果就好. #include <cstdio> #include <cstring> #include <vector> #include <algorithm> #

hdu1255--覆盖的面积(线段树+离散化+扫描线)

E - 覆盖的面积 Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input 输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N<=1000),代表矩形的数量,然后是N行数据,每一行包含

POJ 1177/HDU 1828 picture 线段树+离散化+扫描线 轮廓周长计算

求n个图矩形放下来,有的重合有些重合一部分有些没重合,求最后总的不规则图型的轮廓长度. 我的做法是对x进行一遍扫描线,再对y做一遍同样的扫描线,相加即可.因为最后的轮廓必定是由不重合的线段长度组成的,这样理论上是对的 要注意处理高度相同的线段,把底边优先处理(在代码里就是f标记为1的线段),因为若是一个矩形的底边和另一个矩形的上边重合,则这个轮廓肯定不能算 不过POJ和HDU的数据好像都比较弱,我没进行上面的细节处理也AC了,不过一个很简单的数据就会不对,所以还是要处理一下才是真正正确的代码 我

UVA 11983 Weird Advertisement 线段树+离散化+扫描线

有点像HDU 3642的强化版.给你N个矩形的坐标,问题平面上被k个不同的矩形覆盖的面积是多少. 当初HDU 3642 是直接一个一个手写的,这里的k虽然说只有10,合并过成一个一个手写也是相当蛋疼的,不过仔细想一下,不难推出一般性的关系,然后直接用循环搞就好了.不过我还是因为有个地方忘记初始化WA了2发,真是弱o(╯□╰)o 注意每个房子代表一个点,而我们要把他转化成线段,对坐标进行一些简单的变换即可. #include <cstdio> #include <cstring> #