ACM学习历程—POJ1151 Atlantis(扫描线 && 线段树)
Description
Input
Output
Sample Input
2
10 10 20 20
15 15 25 25.5
0
Sample Output
Test case #1
Total explored area: 180.00
题目就是求所有矩形的并面积。
通过查阅知道了是扫描线,了解了扫描线的原理,用线段树手写了一下,结果PushUp函数写搓了。。看了AC的代码才知道了原因。
做法就是通过对纵坐标有序化,然后创建区间。
然后通过横向扫描过去,得到每段横向段的高度,乘以宽度就是面积了。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define LL long long using namespace std; //线段树
//扫描线
const int maxn = 205;
struct node
{
int lt, rt;
double height;
int num;
}tree[4*maxn]; struct Line
{
double x;
double y1, y2;
bool isLeft;
}line[maxn]; bool cmp(Line a, Line b)
{
return a.x < b.x;
} double y[maxn]; //向上更新
void PushUp(int id)
{
if(tree[id].num > 0)
{
tree[id].height = y[tree[id].rt] - y[tree[id].lt];
return;
}
if(tree[id].lt+1 == tree[id].rt)
tree[id].height = 0;
else
tree[id].height = tree[id<<1].height + tree[id<<1|1].height;
} //建立线段树
void Build(int lt, int rt, int id)
{
tree[id].lt = lt;
tree[id].rt = rt;
tree[id].height = 0;//每段的初值,根据题目要求
tree[id].num = 0;
if (lt+1 == rt)
{
//tree[id].val = 1;
return;
}
int mid = (lt + rt) >> 1;
Build(lt, mid, id<<1);
Build(mid, rt, id<<1|1);
//PushUp(id);
} //寻找符合修改的区间通过判断num进行修改
void Updata(int id,Line p)
{
if(p.y1 <= y[tree[id].lt] && p.y2 >= y[tree[id].rt])
{
if (p.isLeft > 0)
tree[id].num++;
else
tree[id].num--;
PushUp(id);
return;
}
int mid = (tree[id].lt+tree[id].rt) >> 1;
if (p.y1 < y[mid])
Updata(id<<1, p);
if (p.y2 > y[mid])
Updata(id<<1|1, p);
PushUp(id);
} int n; void Input()
{
double x1, y1, x2, y2;
int cnt = 1;
for (int i = 0; i < n; ++i)
{
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
y[cnt] = y1;
y[cnt+1] = y2; line[cnt].x = x1;
line[cnt].y1 = y1;
line[cnt].y2 = y2;
line[cnt].isLeft = true; line[cnt+1].x = x2;
line[cnt+1].y1 = y1;
line[cnt+1].y2 = y2;
line[cnt+1].isLeft = false;
cnt += 2;
}
sort(y+1, y+1+2*n);
sort(line+1, line+1+2*n, cmp);
Build(1, 2*n, 1);
} double Work()
{
double ans = 0;
Updata(1, line[1]);
int len = 2*n;
for (int i = 2; i <= len; ++i)
{
ans += (line[i].x-line[i-1].x) * tree[1].height;
Updata(1, line[i]);
}
return ans;
} int main()
{
//freopen("test.in", "r", stdin);
int times = 1;
while (scanf("%d", &n) != EOF && n)
{
Input();
double ans = Work();
printf("Test case #%d\n", times);
printf("Total explored area: %.2lf\n\n", ans);
times++;
}
return 0;
}
ACM学习历程—POJ1151 Atlantis(扫描线 && 线段树)的更多相关文章
- poj1151 Atlantis——扫描线+线段树
题目:http://poj.org/problem?id=1151 经典的扫描线问题: 可以用线段树的每个点代表横向被矩形上下边分割开的每一格,这样将一个矩形的出现或消失化为线段树上的单点修改: 每个 ...
- ACM学习历程—HDU 5289 Assignment(线段树 || RMQ || 单调队列)
Problem Description Tom owns a company and he is the boss. There are n staffs which are numbered fro ...
- ACM学习历程—HDU 2795 Billboard(线段树)
Description At the entrance to the university, there is a huge rectangular billboard of size h*w (h ...
- poj1151 Atlantis (线段树+扫描线+离散化)
有点难,扫描线易懂,离散化然后线段树处理有点不太好理解. 因为这里是一个区间,所有在线段树中更新时,必须是一个长度大于1的区间才是有效的,比如[l,l]这是一根线段,而不是区间了. AC代码 #inc ...
- ACM学习笔记:可持久化线段树
title : 可持久化线段树 date : 2021-8-18 tags : 数据结构,ACM 可持久化线段树 可以用来解决线段树存储历史状态的问题. 我们在进行单点修改后,线段树只有logn个(一 ...
- POJ 1151 Atlantis (扫描线+线段树)
题目链接:http://poj.org/problem?id=1151 题意是平面上给你n个矩形,让你求矩形的面积并. 首先学一下什么是扫描线:http://www.cnblogs.com/scau2 ...
- [HDU1542]Atlantis(扫描线+线段树)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- 【POJ1151】Atlantis(线段树,扫描线)
[POJ1151]Atlantis(线段树,扫描线) 题面 Vjudge 题解 学一学扫描线 其实很简单啦 这道题目要求的就是若干矩形的面积和 把扫描线平行于某个轴扫过去(我选的平行\(y\)轴扫) ...
- hdu1542 Atlantis(扫描线+线段树+离散)矩形相交面积
题目链接:点击打开链接 题目描写叙述:给定一些矩形,求这些矩形的总面积.假设有重叠.仅仅算一次 解题思路:扫描线+线段树+离散(代码从上往下扫描) 代码: #include<cstdio> ...
随机推荐
- Android TelephonyManager类的使用
TelephonyManager类主要提供了一系列获取手机与通讯相关的状态和信息的get方法,包含手机用户的信息.手机SIM的状态.电信网络的状态等. TelephonyManager类的对象的获取: ...
- Java的Executor框架和线程池实现原理
Java的Executor框架 1,Executor接口 public interface Executor { void execute(Runnable command); } Executor接 ...
- HDFS源码分析数据块之CorruptReplicasMap
CorruptReplicasMap用于存储文件系统中所有损坏数据块的信息.仅当它的所有副本损坏时一个数据块才被认定为损坏.当汇报数据块的副本时,我们隐藏所有损坏副本.一旦一个数据块被发现完好副本达到 ...
- VIM中保存编辑的只读文件
如何在VIM中保存编辑的只读文件 你是否会和我一样经常碰到这样的情景:在VIM中编辑了一个系统配置文件,当需要保存时才发现当前的用户对该文件没有写入的权限.如果已 经做了很多修改,放弃保存的确很懊恼, ...
- 关于React的Container&Presentational Component模型结构分析
react.js javascript 3 之前翻译了两篇关于Container&Presentational Component模型的文章,一篇是基础的Container和Component ...
- vue-strap 修改Modal组件
在用到vue-strap的Modal组件时,会有两个默认按钮,查看官方文档配置如下: 可以看到,ok-text和cancel-text都有一个默认值,在使用时即使不给这两个选项赋值,也会显示两个默认文 ...
- 使用OpenSessionInViewFilter的注意事项
假设在你的应用中Hibernate是通过spring 来管理它的session.如果在你的应用中没有使用OpenSessionInViewFilter或者OpenSessionInViewInterc ...
- HttpClient 访问 https 出现peer can't
package util; import java.security.cert.CertificateException; import javax.net.ssl.SSLContext;import ...
- windowsphone8.1学习笔记之应用数据(三)
之前说了如何操作文本文件,如果是图片文件或者其他的二进制文件则需要操作文件的Stream或者Buffer数据.就需要用到DataReader和DataWriter这两个类了,这个的好好的练一下,以后的 ...
- 九度OJ 1023:EXCEL排序 (排序)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:14605 解决:3307 题目描述: Excel可以对一组纪录按任意指定列排序.现请你编写程序实现类似功能. 对每个测试用例 ...