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> ...
随机推荐
- 未加载Microsoft.SqlServer.management.sdk.sfc version......
这个问题卡了我好久,于是决定记录下来,我这里缺失的是Microsoft.SqlServer.management.sdk.sfc version 12.0.0,当然你也可能后面是11开头的, 这个是由 ...
- 【Atheros】如何在驱动中禁用ACK
上一篇文章讲了如何禁用载波侦听(CSMA)和退避(BACKOFF)的方法,这一篇介绍如何禁用ACK. 禁用ACK主要分为三部分: 1. 在发送端设置不等待ACK回来就继续发送: 2. 在接收端设置收到 ...
- 动态内存分配(Dynamic memory allocation)
下面的代码片段的输出是什么?为什么? 解析:这是一道动态内存分配(Dynamic memory allocation)题. 尽管不像非嵌入式计算那么常见,嵌入式系统还是有从堆(heap)中动态分 ...
- php部分--头像上传预览
前台页面显示 <style type="text/css"> #yl{ width:200px; height:300px; background-image:url( ...
- 【BZOJ4237】稻草人 cdq分治+单调栈+二分
[BZOJ4237]稻草人 Description JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田 ...
- EasyPlayerPro(Windows)流媒体播放器开发之接口设计
EasyPlayerPro(windows)接口说明如下: EasyPlayerPro_Open 说明:打开一个媒体流或者媒体文件进行播放,同时返回一个 player 对象指针 参数说明: fileU ...
- 引用变量的类型强转以及InstanceOf方法的使用
引用到的类: class Person{ String name; } class Student extends Person{ String sut_no; } class ClassMate e ...
- 【题解】[JSOI2008]最大数
[题解][P1198 JSOI2008]最大数 正难则反,意想不到. 这道题是动态让你维护一个数列,已经在数列里面的数据不做改变,每次在最后加上一个数,强制在线. 既然正着做很难,考虑如果时间倒流,不 ...
- pyinstaller使用
python pyinstaller.py [-Fw] ???.py -F 将相关配件(dll.oxc)合成到单个exe文件 -w exe启动时不打开console窗口
- linux下编译安装python
从官网下载指定的源码包 https://www.python.org/downloads/source/ 把源码文件以二进制方式上传到linux服务器 安装python需要用到gcc工具,首先查看gc ...