题目原链接:http://poj.org/problem?id=1151

题目中文翻译:

POJ 1151 Atlantis

Time Limit: 1000MS

 

Memory Limit: 10000K

Total Submissions: 25769

 

Accepted: 9477

Description

有几个古希腊文本包含传说中的亚特兰蒂斯岛的描述。 其中一些文本甚至包括岛屿部分地图。 但不幸的是,这些地图描述了亚特兰蒂斯的不同区域。 您的朋友Bill必须知道地图的总面积。 你(不明智地)自告奋勇写了一个计算这个数量的程序。

Input

输入包含几个测试用例。 每个测试用例都以一行包含一个整数n(1 <= n <= 100)开始,指示可用的地图。以下n行描述了每个地图。 这些行中的每一行包含四个数字x1; y1; x2; y2(0 <= x1 <x2 <= 100000; 0 <= y1 <y2 <= 100000),不一定是整数。 值(x1; y1)和(x2; y2)是地图左上角和右下角的坐标。

输入文件以包含单个0的行作为终止。不处理它。

Output

对于每个测试用例,您的程序应输出一个部分。 每个部分的第一行必须是“Test case #k”,其中k是测试用例的编号(从1开始)。 第二个必须是“Total explored area:a”,其中a是总探索区域(即此测试用例中所有矩形的覆盖区域),精确到小数点后两位数。

在每个测试用例后输出一个空行。

Sample Input

2

10 10 20 20

15 15 25 25.5

0

Sample Output

Test case #1

Total explored area: 180.00

解题思路:

本人太菜,无法描述,请看大佬详解:AKIOI

AC代码:

(由此大佬博客借鉴而来:code)

 #include<cstdio>
#include<iostream>
#include<algorithm> using namespace std; struct kkk{//线段树
int l,r;//线段树的左右整点
int c;//c用来记录重叠情况
double cnt,lf,rf;//cnt用来计算实在的长度,lf,rf分别是对应的左右真实的浮点数端点
}s[]; struct k2{
double x,y1,y2;
int f;
}l[];
//把一段段平行于y轴的线段表示成数组 ,
//x是线段的x坐标,y1,y2线段对应的下端点和上端点的坐标
//一个矩形 ,左边的那条边f为1,右边的为-1,
//用来记录重叠情况,可以根据这个来计算,kkk节点中的c double y[];//记录y坐标的数组 bool cmp(k2 a,k2 b) {
return a.x < b.x;
} void build(int t,int l,int r) {
s[t].l = l;s[t].r = r;
s[t].cnt = s[t].c = ;
s[t].lf = y[l];
s[t].rf = y[r];
if(l + == r) return ;
int mid = (l + r) >> ;
build(t << ,l,mid);
build(t << | ,mid,r);
} void calen(int t) {//计算长度
if(s[t].c > ) {// t对应对节点有线段覆盖
s[t].cnt = s[t].rf - s[t].lf;
return ;
}
// 现在是t对应的线段没有完整的被覆盖,但是他的孩子节点可能部分被覆盖
if(s[t].l + == s[t].r) s[t].cnt = ;//线段树叶子结点,代表一个点,特判,长度为0
else s[t].cnt = s[t<<].cnt + s[t<<|].cnt;//否则,用孩子的和来表示
} void update(int t,k2 e) {//加入线段e,后更新线段树
if(e.y1 == s[t].lf && e.y2 == s[t].rf) {//如果正好找到区间
s[t].c += e.f;
calen(t);
return ;
}
if(e.y2 <= s[t<<].rf) update(t<<,e);//下传左儿子
else if(e.y1 >= s[t<<|].lf) update(t<<|,e);//下传右儿子
else {//左右儿子都下传
k2 tmp = e;
tmp.y2 = s[t<<].rf;
update(t<<,tmp);
tmp = e;
tmp.y1 = s[t<<|].lf;
update(t<<|,tmp);
}
calen(t);
} int main() {
int i,n,t,aa = ;
double x1,y1,x2,y2;
while(scanf("%d",&n),n) {
aa++;
t = ;
for(int i = ;i <= n; i++) {
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
l[t].x = x1;
l[t].y1 = y1;
l[t].y2 = y2;
l[t].f = ;
y[t++] = y1;
l[t].x = x2;
l[t].y1 = y1;
l[t].y2 = y2;
l[t].f = -;
y[t++] = y2;
}
sort(l+,l+t,cmp);
sort(y+,y+t);
build(,,t-);//建树
update(,l[]);//下传lazy标记
double res = ;
for(int i = ;i < t; i++) {
res += s[].cnt * (l[i].x - l[i-].x);
update(,l[i]);
}
printf("Test case #%d\nTotal explored area: %.2f\n\n",aa,res);
}
}

POJ 1151 Atlantis(扫描线)的更多相关文章

  1. POJ 1151 Atlantis (扫描线+线段树)

    题目链接:http://poj.org/problem?id=1151 题意是平面上给你n个矩形,让你求矩形的面积并. 首先学一下什么是扫描线:http://www.cnblogs.com/scau2 ...

  2. POJ 1151 Atlantis 矩形面积求交/线段树扫描线

    Atlantis 题目连接 http://poj.org/problem?id=1151 Description here are several ancient Greek texts that c ...

  3. POJ 1151 Atlantis(线段树-扫描线,矩形面积并)

    题目链接:http://poj.org/problem?id=1151 题目大意:坐标轴上给你n个矩形, 问这n个矩形覆盖的面积 题目思路:矩形面积并. 代码如下: #include<stdio ...

  4. hdu 1542&&poj 1151 Atlantis[线段树+扫描线求矩形面积的并]

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

  5. POJ 1151 Atlantis 线段树+离散化+扫描线

    这次是求矩形面积并 /* Problem: 1151 User: 96655 Memory: 716K Time: 0MS Language: G++ Result: Accepted */ #inc ...

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

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

  7. POJ 1151 Atlantis 求矩阵面积并 扫描线 具体解释

    题意: 给定n个矩阵的左下角和右上角坐标,求矩阵面积并(矩阵总是正放的,即与x轴y轴都平行) 思路: 扫描线裸题 http://www.cnblogs.com/fenshen371/p/3214092 ...

  8. POJ 1151 Atlantis(经典的线段树扫描线,求矩阵面积并)

    求矩阵的面积并 采用的是区间更新 #include <iostream> #include <stdio.h> #include <string.h> #inclu ...

  9. poj 1151 Atlantis (离散化 + 扫描线 + 线段树 矩形面积并)

    题目链接题意:给定n个矩形,求面积并,分别给矩形左上角的坐标和右上角的坐标. 分析: 映射到y轴,并且记录下每个的y坐标,并对y坐标进行离散. 然后按照x从左向右扫描. #include <io ...

随机推荐

  1. ORACLE 8i 遇到报错:ORA-01631: max # extents (505) reached in table

    近期在客户的一个8i生产库上使用statspack.发现alert中有报错: Mon Jun 16 13:17:52 2014 Errors in file /oracle/8.1.7/admin/p ...

  2. HDU 2669 Romantic(扩展欧几里德)

    题目链接:pid=2669">http://acm.hdu.edu.cn/showproblem.php?pid=2669 Problem Description The Sky is ...

  3. 安装Sublime配合quick-cocos2d-x开发

    下载地址 Sublime下载地址 安装 Package Control 在Sublime中,按Ctrl+~打开控制台,输入: Sublime Text2 import urllib2,os; pf=' ...

  4. 【转载】FAT12格式的引导程序(2)

     1.用WinImage来写入到引导区的详细步骤: 启动WinImage后,打开“文件”菜单,单击菜单中的“打开”命令. 选择之前保存的磁盘镜像文件“boot.img”或者“boot.ima”. 打开 ...

  5. TinyXML学习:TiXmlBase类

    TiXmlBase: 作为整个TinyXML模型的基类,除了可以提供一些实用功能外,它几乎没有什么作用 TiXmlBase的友元类: friend class TiXmlNode; friend cl ...

  6. ios+Appium+Java

    To run iOS tests, you can follow these steps : (Note : I am using Java language here in Eclipse IDE ...

  7. 程序设计之另一种读写函数---writev,readv

    read()和write()系统调用每次在文件和进程的地址空间之间传送一块连续的数据.但是,应用有时也需要将分散在内存多处地方的数据连续写到文件中,或者反之.在这种情况下,如果要从文件中读一片连续的数 ...

  8. IP数据报首部格式

    IP协议提供不可靠.无连接的数据报传送服务. 不可靠:尽力而为地传输,不保证IP数据报能成功到达目的地. 无连接:每一个数据报之间相互独立地进行路由选择,可不按发送顺序接收. IP首部格式例如以下: ...

  9. QT下QThread学习(二)

    学习QThread主要是为了仿照VC下的FTP服务器写个QT版本.不多说,上图. FTP服务器的软件结构在上面的分析中就已经解释了,今天要解决的就是让每一个客户端的处理过程都可以按一个线程来单独跑.先 ...

  10. linux下自动创建设备文件节点---class

    在驱动模块初始化函数中实现设备节点的自动创建 我们在刚开始写Linux设备驱动程序的时候,很多时候都是利用mknod命令手动创建设备节点,实际上Linux内核为我们提供了一组函数,可以用来在模块加载的 ...