Atlantis

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

Total Submission(s): 9032    Accepted Submission(s): 3873

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
 
Recommend
linle   |   We have carefully selected several similar problems for you:  1828 

pid=1255" target="_blank" style="color:rgb(26,92,200); text-decoration:none">1255 1540 2795 1823 

 

pid=1542" style="color:rgb(26,92,200); text-decoration:none">Statistic | 

pid=1542" style="color:rgb(26,92,200); text-decoration:none">Submit | Discuss | 

pid=1542" style="color:rgb(26,92,200); text-decoration:none">Note

第一次做线段树+扫描线+离散化..当然是不会做的 甚至都没听说过

所以百度+查资料+看了n久 最终有了一点眉目。。

离散化是程序设计中一个很经常使用的技巧,它能够有效的减少时间复杂度。

其基本思想就是在众多可能的情况中“仅仅考虑我须要用的值”。离散化能够改进一个低效的算法,甚至实现根本不可能实现的算法。

要掌握这个思想。必须从大量的题目中理解此方法的特点。

在这里先依照x大小排序。

(10,15,20。25)这种话我们就知道矩形的长,然后就该求宽了。知道宽面积

不就是手到擒来嘛。至于求宽就是把y坐标离散化,然后開始建树。扫描求宽了。

记得一次增加一个y坐标,事实上

就是一个y=?的一条线、每加入两条线计算一次面积(假设加入1 2 3次计算两次面积求和),然后求和

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

这就是本题例题的四个扫描线。。第一次是标号为1的左边。第二次面积为红色,第三次为绿色。第四次就是蓝色

#include <stdio.h>
#include <algorithm>
using namespace std;
struct node1
{
double x,y1,y2,flag;//flag表示该边是入边还是出边
}c[205];
struct node2
{
double left,right,len,s;//s标记这条边是否全然覆盖
int l,r;
}d[205*4];
double y[205];//全部y坐标
bool cmp(node1 a,node1 b)
{
return a.x<b.x;
}
void build(int root,int l,int r)
{
d[root].l=l;
d[root].r=r;
d[root].left=y[l];
d[root].right=y[r];
d[root].len=0;
d[root].s=0;
if(l+1==r)
return ;
int mid=(l+r)/2;
build(root*2,l,mid);
build(root*2+1,mid,r);//不是mid+1,比方仅仅有(10,15,20三个y坐标,应该出现三个范围(10 20)(10 15)(15 20))而不是(10 20)(10 15)
}
void cal(int root)
{
if(d[root].s>0)非0 全然覆盖
d[root].len=d[root].right-d[root].left;
else if(d[root].r-d[root].l==1)
d[root].len=0;
else
d[root].len=d[root*2].len+d[root*2+1].len;
}
void update(int root,node1 x)
{
if(d[root].left==x.y1&&d[root].right==x.y2)
{
d[root].s+=x.flag;
cal(root);
return ;
}
if(x.y1>=d[root*2].right) update(root*2+1,x);
else if(x.y2<=d[root*2+1].left) update(root*2,x);
else
{
node1 temp;
temp=x;
temp.y2=d[root*2].right;
update(root*2,temp);
temp=x;
temp.y1=d[root*2+1].left;
update(root*2+1,temp);
}
cal(root);
return ;
}
int main()
{
int n,ncase=1;
while(scanf("%d",&n)&&n)
{
int t=1;
for(int i=0;i<n;i++)
{
double x1,y1,x2,y2;
scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
c[t].x=x1,c[t].y1=y1,c[t].y2=y2,c[t].flag=1,y[t++]=y1;//入边<span style="white-space:pre"> </span>
c[t].x=x2,c[t].y1=y1,c[t].y2=y2,c[t].flag=-1,y[t++]=y2;//出边
}
sort(c+1,c+t,cmp);
sort(y+1,y+t);
build(1,1,t-1);
update(1,c[1]);
double sum=0;
for(int i=2;i<t;i++)
{
sum+=(c[i].x-c[i-1].x)*d[1].len;
update(1,c[i]);
}
printf("Test case #%d\nTotal explored area: %.2lf\n\n",ncase++,sum);
}
return 0;
}

hdu1542 Atlantis (线段树+扫描线+离散化)的更多相关文章

  1. hdu1542 Atlantis 线段树--扫描线求面积并

    There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...

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

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

  3. HDU 1542 - Atlantis - [线段树+扫描线]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...

  4. POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]

    题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...

  5. HDU1542 Atlantis —— 求矩形面积并 线段树 + 扫描线 + 离散化

    题目链接:https://vjudge.net/problem/HDU-1542 There are several ancient Greek texts that contain descript ...

  6. HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)

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

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

    有点难,扫描线易懂,离散化然后线段树处理有点不太好理解. 因为这里是一个区间,所有在线段树中更新时,必须是一个长度大于1的区间才是有效的,比如[l,l]这是一根线段,而不是区间了. AC代码 #inc ...

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

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

  9. POJ 1151 - Atlantis 线段树+扫描线..

    离散化: 将所有的x轴坐标存在一个数组里..排序.当进入一条线段时..通过二分的方式确定其左右点对应的离散值... 扫描线..可以看成一根平行于x轴的直线..至y=0开始往上扫..直到扫出最后一条平行 ...

随机推荐

  1. V-rep学习笔记:Geometric Constraint Solver(几何约束求解)

    The geometric constraint solver is slower and less precise at solving kinematic problems, but might ...

  2. 3、redis之java client环境搭建

    JAVA Client环境搭建 POM: <dependency> <groupId>redis.clients</groupId> <artifactId& ...

  3. excel如何快速更改表格边框的颜色

    1.当完成基本的表格设置之后,对颜色不甚满意,怎么办 2.重新给表格选择一种颜色,这里会出现一个“笔”形状的鼠标箭头,不用理睬她 3.再次给表格统一加边框即可(开始--边框--所有框线)

  4. Dlib三维点云示例

    Dlib三维点云示例 源代码来自Dlib的示例代码http://dlib.net/3d_point_cloud_ex.cpp.html 在windows下需要链接winmm``comctl32``gd ...

  5. .NET 中的 async/await 异步编程

    原文出处: Teroy 的博客 前言 最近在学习Web Api框架的时候接触到了async/await,这个特性是.NET 4.5引入的,由于之前对于异步编程不是很了解,所以花费了一些时间学习一下相关 ...

  6. Spring Cloud Zuul性能调整

    Spring Cloud 版本: Dalston.SR5 这两天通过JMeter测了一下Spring Cloud Zuul的性能,用的是两台虚机8核8G和4核8G,宿主机是10核逻辑20核,代理的服务 ...

  7. aapt 命令可应用于查看apk包名、主activity、版本等很多信息

    aapt即Android Asset Packaging Tool,在SDK的build-tools目录下,本文小结了一下该工具的用法. 配置环境变量后可直接在cmd使用该命令 http://blog ...

  8. intellij idea强制更新索引

    intellij idea使用时间长了,许多包安了又卸.卸了又安,导致索引文件有些不正常. 删除~/.Intellij Idea/下的index和cache即可彻底更新.

  9. 部署hadoop的开发环境

    第一步:安装jdk 由于hadoop是java开发的,所以需要JDK来运行代码.这里安装的是jdk1.6. jdk的安装见http://www.cnblogs.com/tommyli/archive/ ...

  10. k8s实战读书笔记

    一.概述 kubernetes中Service是真实应用的抽象,将用来代理Pod,对外提供固定IP作为访问入口,这样通过访问Service便能访问到相应的Pod,而对访问者来说只需知道Service的 ...