POJ 1151 Atlantis(扫描线)
题目原链接: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(扫描线)的更多相关文章
- POJ 1151 Atlantis (扫描线+线段树)
题目链接:http://poj.org/problem?id=1151 题意是平面上给你n个矩形,让你求矩形的面积并. 首先学一下什么是扫描线:http://www.cnblogs.com/scau2 ...
- POJ 1151 Atlantis 矩形面积求交/线段树扫描线
Atlantis 题目连接 http://poj.org/problem?id=1151 Description here are several ancient Greek texts that c ...
- POJ 1151 Atlantis(线段树-扫描线,矩形面积并)
题目链接:http://poj.org/problem?id=1151 题目大意:坐标轴上给你n个矩形, 问这n个矩形覆盖的面积 题目思路:矩形面积并. 代码如下: #include<stdio ...
- hdu 1542&&poj 1151 Atlantis[线段树+扫描线求矩形面积的并]
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- POJ 1151 Atlantis 线段树+离散化+扫描线
这次是求矩形面积并 /* Problem: 1151 User: 96655 Memory: 716K Time: 0MS Language: G++ Result: Accepted */ #inc ...
- POJ 1151 - Atlantis 线段树+扫描线..
离散化: 将所有的x轴坐标存在一个数组里..排序.当进入一条线段时..通过二分的方式确定其左右点对应的离散值... 扫描线..可以看成一根平行于x轴的直线..至y=0开始往上扫..直到扫出最后一条平行 ...
- POJ 1151 Atlantis 求矩阵面积并 扫描线 具体解释
题意: 给定n个矩阵的左下角和右上角坐标,求矩阵面积并(矩阵总是正放的,即与x轴y轴都平行) 思路: 扫描线裸题 http://www.cnblogs.com/fenshen371/p/3214092 ...
- POJ 1151 Atlantis(经典的线段树扫描线,求矩阵面积并)
求矩阵的面积并 采用的是区间更新 #include <iostream> #include <stdio.h> #include <string.h> #inclu ...
- poj 1151 Atlantis (离散化 + 扫描线 + 线段树 矩形面积并)
题目链接题意:给定n个矩形,求面积并,分别给矩形左上角的坐标和右上角的坐标. 分析: 映射到y轴,并且记录下每个的y坐标,并对y坐标进行离散. 然后按照x从左向右扫描. #include <io ...
随机推荐
- 聊聊高并发(二十四)解析java.util.concurrent各个组件(六) 深入理解AQS(四)
近期总体过了下AQS的结构.也在网上看了一些讲AQS的文章,大部分的文章都是泛泛而谈.又一次看了下AQS的代码,把一些新的要点拿出来说一说. AQS是一个管程.提供了一个主要的同步器的能力,包括了一个 ...
- Linux性能查看与分析--命令行工具介绍
本文介绍工作中常用的几个linux性能查看命令:top,sar,vmstat,iostat,pidstat等. 1.top top是最常用的linux性能分析工具,它能够实时的显示系统中各个进程的资源 ...
- 项目Beta冲刺(团队6/7)
项目Beta冲刺(团队6/7) 团队名称: 云打印 作业要求: 项目Beta冲刺(团队) 作业目标: 完成项目Beta版本 团队队员 队员学号 队员姓名 个人博客地址 备注 221600412 陈宇 ...
- c++string 输入换行符
string 一次只能输入一行,不含换行符.可以自己添加换行符 和输入行数.例如:#include <iostream>#include <string>using names ...
- 电脑突然死机,编译报错dll缺少依赖项
由于ASP.NET缓存没更新的问题(我的就是这个问题.电脑突然死机导致的). 把这个文件夹下的文件所有删除C:\Windows\Microsoft.NET\Framework\v2.0.50727\T ...
- BZOJ 2244: [SDOI2011]拦截导弹 DP+CDQ分治
2244: [SDOI2011]拦截导弹 Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度.并且能够拦截 ...
- 在Java中如何正确地终止一个线程
1.使用Thread.stop()? 极力不推荐此方式,此函数不安全且已废弃,具体可参考Java API文档 2.设置终止标识,例如: import static java.lang.System.o ...
- (深入理解计算机系统) bss段,data段、text段、堆(heap)和栈(stack)
bss段: bss段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域. bss是英文Block Started by Symbol的简称. bss段属于静态内存分配. ...
- POJ2955 Brackets —— 区间DP
题目链接:https://vjudge.net/problem/POJ-2955 Brackets Time Limit: 1000MS Memory Limit: 65536K Total Su ...
- python读取一个文件的每一行判断是否为素数,并把结果写到另一个文件中
刚刚学习python的菜鸟,这道题包括:文件的读写,python的参数调用,异常的使用,函数的使用 创建一个文本文件inti_prime.txt 执行命令:python Prime.py init_p ...