HDU - 1542 Atlantis —— 扫描线

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Lngxling/article/details/81324965

Atlantis

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


 

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

题意:

给定n个矩形,求其合并后的面积

思路:

扫描线裸题,代码是从下至上扫描

将每个矩形的上下两条边存进结构体数组,按高度排序

将每个矩形的左右两个x坐标存进数组,按从小到大排序进行离散化,去不去重都可以,去重后离散化的坐标是连续的

从下至上依次扫描边,线段树中维护的是矩形投影到x轴上的长度,遇到下边就加入线段树,遇到上边就清除线段树

每次用线段树维护出的长度乘高度差即为面积

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <vector>
#include <bitset>
#define max_ 1100
#define inf 0x3f3f3f3f
#define ll long long
#define les 1e-8
#define mod 364875103
using namespace std;
struct node
{
    int l,r;
    int w;
    double len;
};
struct node tree[max_*8];
struct edge
{
    double l,r;
    double h;
    int f;
    bool operator < (const edge &a)const
    {
        return h<a.h;
    }
};
struct edge e[max_*2];
double x[max_*2];
int n;
int casnum=1;
void built(int i,int l,int r)
{
    tree[i].l=l;
    tree[i].r=r;
    tree[i].w=0;
    tree[i].len=0;
    if(l+1==r)
    return;
    int mid=(l+r)>>1;
    built(i<<1,l,mid);
    built(i<<1|1,mid,r);
}
void up(int i)
{
    if(tree[i].w)
    tree[i].len=x[tree[i].r]-x[tree[i].l];
    else
    tree[i].len=tree[i<<1].len+tree[i<<1|1].len;
}
void updata(int i,int l,int r,int v)
{
    if(tree[i].l==l&&tree[i].r==r)
    {
        tree[i].w+=v;
        up(i);
        return;
    }
    int mid=(tree[i].l+tree[i].r)>>1;
    if(r<=mid)
    updata(i<<1,l,r,v);
    else if(l>=mid)
    updata(i<<1|1,l,r,v);
    else
    {
        updata(i<<1,l,mid,v);
        updata(i<<1|1,mid,r,v);
    }
    up(i);
}
int main(int argc, char const *argv[]) {
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0)
        break;
        printf("Test case #%d\n",casnum++ );
        for(int i=1;i<=n;i++)
        {
            double x1,x2,y1,y2;
            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
            int p=i*2-1;
            int q=i*2;
            e[p].l=e[q].l=x1;
            e[p].r=e[q].r=x2;
            e[p].h=y1;
            e[p].f=1;
            x[p]=x1;
            e[q].h=y2;
            e[q].f=-1;
            x[q]=x2;
        }
        sort(x+1,x+1+2*n);
        sort(e+1,e+1+2*n);
        built(1,1,2*n);
        double ans=0;
        for(int i=1;i<2*n;i++)
        {
            int l=lower_bound(x+1,x+1+2*n,e[i].l)-x;
            int r=lower_bound(x+1,x+1+2*n,e[i].r)-x;
            updata(1,l,r,e[i].f);
            ans+=(e[i+1].h-e[i].h)*tree[1].len;
        }
        printf("Total explored area: %.2lf\n",ans);
        printf("\n" );
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Lngxling/article/details/81324965
今日推荐