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> ...
随机推荐
- nodejs初学-----helloworld
近期紧锣密鼓的学习了下nodejs(之前在学php.算入门了吧,可是时间关系,还没写文章,兴许要搞安卓和大数据,总之比較忙哈,计划上php要排到后面了,还请广大小伙伴不要着急) 先抄一句:Node.j ...
- 淘宝数据库OceanBase SQL编译器部分 源代码阅读--解析SQL语法树
OceanBase是阿里巴巴集团自主研发的可扩展的关系型数据库,实现了跨行跨表的事务,支持数千亿条记录.数百TB数据上的SQL操作. 在阿里巴巴集团下,OceanBase数据库支持了多个重要业务的数据 ...
- 使用css counter来美化代码片段的样式
博客园默认的代码片段样式不太美观,特别是复制代码时会把前面的行号也复制下来,操作起来比较麻烦.最近看到一种使用CSS计数器来美化代码片段的方法,于是研究了一下计数器的使用,在此做个笔记. 这是官网的例 ...
- 必会必知git
git必会必知 1 前言 git前身是BitKeeper,但是他不是开源软件,不符合当时开源趋势,于是就会有了开源的git,git开发只用了十天时间.目前git是公司开发必不可少的一个工具,用于多 ...
- erlang中的图片下载
问题如题,这是在一个群里问的一个的问题.其实就是http的Server的上传下载的功能. ibrowse:start().ibrowse:send_req("http://img1.gti ...
- Android:实现两个Activity相互切换而都不走onCreate()
本文要实现的目的是: 有3个Activity: A,B,C.从A中能够进入B,B中能够进入C.而且B和C之间可能须要多次相互切换,因此不能使用普通的startActivity-finish方式,由于又 ...
- 2014新浪研发project师实习笔试(哈尔滨站)
刚经历了新浪笔试,写篇博客记录一下下.方便以后查看. 一.基础题 1.栈和队列的异同点. 2.算法性能的4个评价标准. 排序算法中最稳定的算法. 那几个算法的空间复杂度是O(1)的. 3.线性表,平衡 ...
- 37、pendingIntent 点击通知栏进入页面
转载: http://blog.csdn.net/yuzhiboyi/article/details/8484771 https://my.oschina.net/youranhongcha/blog ...
- COGS410. [NOI2009] 植物大战僵尸
410. [NOI2009] 植物大战僵尸 ★★★ 输入文件:pvz.in 输出文件:pvz.out 简单对比时间限制:2 s 内存限制:512 MB [问题描述] Plants vs ...
- [原]js获取dom元素的实际位置及相对坐标
关键API: Element.getBoundingClientRect() mdn:https://developer.mozilla.org/en-US/docs/Web/API/Element/ ...