hdu 1542 Atlantis(线段树 线性扫描)

原创 2017年01月03日 10:06:24
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
 

Source
 


题意:给你n个矩形,求它们的面积,重复的不重复计算

思路:线段树的线性扫描,由于坐标可能很大,需要先离散化处理;

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=105;
struct node1{
    double x1,x2,h;
    int f;
}s[2*N];
struct node2{
    int l,r,cnt;
    double len;
}str[6*N];
double a[2*N];
bool cmp(node1 aa,node1 bb)
{
    return aa.h<bb.h;
}
int find(double x,int l,int r)
{
    while(l<=r)
    {
        int temp=(l+r)/2;
        if(x==a[temp]) return temp;
        else if(x<a[temp]) r=temp-1;
        else l=temp+1;
    }
}
void build(int l,int r,int n)
{
    str[n].l=l;
    str[n].r=r;
    str[n].len=0;
    str[n].cnt=0;
    if(l==r)
        return;
    int temp=(l+r)/2;
    build(l,temp,2*n);
    build(temp+1,r,2*n+1);
}
void add(int n)
{
    if(str[n].cnt)
        str[n].len=a[str[n].r+1]-a[str[n].l];
    else if(str[n].l==str[n].r)
        str[n].len=0;
    else
        str[n].len=str[2*n].len+str[2*n+1].len;
}
void updata(int l,int r,int flag,int n)
{
    if(l==str[n].l&&r==str[n].r)
    {
        str[n].cnt+=flag;
        add(n);
        return;
    }
    int temp=(str[n].l+str[n].r)/2;
    if(r<=temp)
        updata(l,r,flag,2*n);
    else if(l>temp)
        updata(l,r,flag,2*n+1);
    else
    {
        updata(l,temp,flag,2*n);
        updata(temp+1,r,flag,2*n+1);
    }
    add(n);
}
int main()
{
    int n;
    int t=1;
    while(~scanf("%d",&n))
    {
        if(n==0) break;
        for(int i=0;i<n;i++)
        {
            double x1,y1,x2,y2;
            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
            s[2*i].x1=x1;s[2*i].x2=x2;s[2*i].h=y1;s[2*i].f=1;
            s[2*i+1].x1=x1;s[2*i+1].x2=x2;s[2*i+1].h=y2;s[2*i+1].f=-1;
            a[2*i]=x1;a[2*i+1]=x2;
        }
        sort(s,s+2*n,cmp);
        sort(a,a+2*n);
        int len=1;
        double temp=a[0];
        for(int i=1;i<2*n;i++)
            if(temp!=a[i])
            {
                a[len++]=a[i];
                temp=a[i];
            }
        build(0,len-1,1);
        double ans=0;
        for(int i=0;i<2*n;i++)
        {
            int l=find(s[i].x1,0,len-1);
            int r=find(s[i].x2,0,len-1)-1;
            updata(l,r,s[i].f,1);
            ans+=str[1].len*(s[i+1].h-s[i].h);
        }
        printf("Test case #%d\n",t++);
        printf("Total explored area: %.2lf\n\n",ans);
    }
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

hdu 1542 Atlantis(线段树&扫描线&面积并)

Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total...

HDU1542——Atlantis(扫描线,线段树,矩形面积并,离散化)

I - Atlantis Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit...

【42.49%】【hdu 1542】Atlantis(线段树扫描线简析)

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submissio...

POJ 1151 & HDU 1542 Atlantis(扫描线模板 线段树 离散化)

POJ 1151 & HDU 1542 Atlantis(扫描线模板 线段树 离散化)

HDU1542 Atlantis(线段树+扫描线)

Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S...

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 这个题目之前用线段切割方法做过,觉得做法经典,但是如果数据量大的话线段切割就力不从心了,后来尝...

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

B - Atlantis Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit S...

hdu1542 Atlantis(扫描线+线段树+离散)矩形相交面积

题目链接:点击打开链接 题目描述:给定一些矩形,求这些矩形的总面积,如果有重叠,只算一次 解题思路:扫描线+线段树+离散(代码从上往下扫描) 代码: #include #include #def...

HDU 1542 Atlantis(线段树扫描线,面积并)

题意: 给你nn (n

HDU 1542 Atlantis 线段树+扫描线

求n个矩形的面积并。 看了一下扫描线,这个东西和某场BC的贪心题目类似,就是一个矩形拆成两个线段,标记一下矩形开始的线段和结束的线段,那么这个矩形的面积就是两条线段所在的坐标差*线段长度..就是线段...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hdu 1542 Atlantis(线段树 线性扫描)
举报原因:
原因补充:

(最多只允许输入30个字)