HDU1542Atlantis(扫描线)
HDU1542Atlantis(扫描线)
题目大意:给你n个覆盖矩形,问最后覆盖的面积。
解题思路:将每一个矩形拆成两条线段,一条是+1的,还有一条是减1的。然后扫描先从上往下扫描,碰到加1的那条线段,那么这条线段范围内的节点的覆盖信息就+1,直到碰到减1这个线段范围内的节点的覆盖信息都须要减1。
这样说可能理解不了,就能够画画矩形然后画下扫描线在理解理解。然后就是须要离散化的建树,由于这里是都double型的。所谓离散化建树的意思就是如今每一个叶子节点代表的是一段区间。而不是单独的一点。
代码:
#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 205;
#define lson(x) (x<<1)
#define rson(x) ((x<<1) | 1)
struct Node {
int l, r, add;
double s;
void set (int l, int r, double s, int add) {
this->l = l;
this->r = r;
this->s = s;
this->add = add;
}
}node[4 * maxn];
struct Line {
double x, y1, y2;
int flag;
Line (double x, double y1, double y2, int flag) {
this->x = x;
this->y1 = y1;
this->y2 = y2;
this->flag = flag;
}
bool operator < (const Line &l) const {
return x < l.x;
}
};
int n;
vector<Line> L;
vector<double> pos;
void pushup(int u) {
if (node[u].add)
node[u].s = pos[node[u].r + 1] - pos[node[u].l];
else if (node[u].l == node[u].r)
node[u].s = 0;
else
node[u].s = node[lson(u)].s + node[rson(u)].s;
}
void build (int u, int l, int r) {
node[u].set (l, r, 0, 0);
if (l == r)
return;
int m = (l + r)>>1;
build(lson(u), l, m);
build(rson(u), m + 1, r);
}
void update (int u, int l, int r, int v) {
if (node[u].l >= l && node[u].r <= r) {
node[u].add += v;
pushup(u);
return;
}
int m = (node[u].l + node[u].r)>>1;
if (l <= m)
update (lson(u), l, r, v);
if (r > m)
update (rson(u), l, r, v);
pushup(u);
}
void init () {
pos.clear();
L.clear();
double x1, y1, x2, y2;
for (int i = 0; i < n; i++) {
scanf ("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
pos.push_back(y1);
pos.push_back(y2);
L.push_back(Line(x1, y1, y2, 1));
L.push_back(Line(x2, y1, y2, -1));
}
sort (pos.begin(), pos.end());
sort (L.begin(), L.end());
pos.erase(unique(pos.begin(), pos.end()), pos.end());
build(1, 0, (int)pos.size() - 1);
}
double solve() {
init();
double ans = 0;
for (int i = 0; i < (int)L.size() - 1; i++) {
int l = lower_bound(pos.begin(), pos.end(), L[i].y1) - pos.begin();
int r = lower_bound(pos.begin(), pos.end(), L[i].y2) - pos.begin();
update (1, l, r - 1, L[i].flag);
// printf ("%.2lf\n", node[1].s);
ans += node[1].s * (L[i + 1].x - L[i].x);
}
return ans;
}
int main () {
int T = 0;
double x1, y1, x2, y2;
while (scanf ("%d", &n) && n) {
printf ("Test case #%d\n", ++T);
printf ("Total explored area: %.2lf\n\n", solve());
}
return 0;
}
HDU1542Atlantis(扫描线)的更多相关文章
- HDU1542--Atlantis(扫描线)
给N个矩形的端点坐标,求矩形覆盖面积和. 原理很简单,从左到右扫描,线段树记录的是纵向覆盖的长度.区间更新.因为坐标是实数而且很大,所以需要离散化. WA+RE+CE+MLE+...一共错了二十多次. ...
- HDU1542-Atlantis【离散化&线段树&扫描线】个人认为很全面的详解
刚上大一的时候见过这种题,感觉好牛逼哇,这都能算 如今已经不打了,不过适当写写题保持思维活跃度还是不错的,又碰到这种题了,想把它弄出来 说实话,智商不够,看了很多解析,花了4.5个小时才弄明白 网上好 ...
- 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)
D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...
- Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)
题目链接:http://codeforces.com/contest/522/problem/D 题目大意: 给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查 ...
- HUD 4007 [扫描线][序]
/* 大连热身B题 不要低头,不要放弃,不要气馁,不要慌张 题意: 坐标平面内给很多个点,放置一个边长为r的与坐标轴平行的正方形,问最多有多少个点在正方形内部. 思路: 按照x先排序,然后确定x在合法 ...
- Atitit 图像扫描器---基于扫描线
Atitit 图像扫描器---基于扫描线 调用范例 * @throws FileExistEx */ public static void main(String[] args) throws Fil ...
- 扫描线+堆 codevs 2995 楼房
2995 楼房 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 地平线(x轴)上有n个矩(lou)形(fan ...
- 【BZOJ-4059】Non-boring sequences 线段树 + 扫描线 (正解暴力)
4059: [Cerc2012]Non-boring sequences Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 440 Solved: 16 ...
- 【BZOJ-4422】Cow Confinement 线段树 + 扫描线 + 差分 (优化DP)
4422: [Cerc2015]Cow Confinement Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 61 Solved: 26[Submi ...
随机推荐
- ssh 带密码私钥 输入密码
$ssh-agent bash $ssh-add -k ~/.ssh/id_rsa Enter passphrase for /home/ubuntu/.ssh/id_rsa: Identity ad ...
- windows cmd 模仿电影黑客
1.win+R 2.输入cmd 3.按F11进入全屏 4.color a 改变颜色为绿色(可能看起来秀一点) 5.dir/s 查看所有文件,就跑起来了,看起来很酷,但是在懂得人眼里,没什么的(所以只能 ...
- 遇到的django问题
问题1: No migrations to apply 删除了migrations中0001_initial.py文件,重新执行 python manage.py makemigrations pyt ...
- CodeForces - 1105D Kilani and the Game(多源BFS+暴力)
题目: 给出一张游戏地图和每个玩家的位置,每次能移动的步数.p个玩家轮流移动占领地图中的格子(当格子已经被占领时就不能在占领了)在每个玩家都不能移动时游戏结束. 问在游戏结束后,每个玩家占领的格子的数 ...
- poj-1163 动态规划
这道题目并不能直接使用递归,因为 7(1) 7(1) 7(1) 7(1) 7(2) 7(1) 7(1) 7(3) 7(3) ...
- Linux启动流程CentOS6和7的区别
目 录 Linux启动流程 I 第1章 CentOS6启动流程 1 1.1 BIOS 1 1.2 MBR 1 1.3 GRUB 1 1.4 kernel(加载内核) ...
- 【JavaEE-面试总结】(未完,待续···)
目录: 一.Java基础 二.JavaEE基础 三.JavaEE进阶 四.数据库 五.数据结构&算法 六.高级(服务器) 一.Java基础 1.1 面向对象(封装.继承.多态) 访问权限修饰符 ...
- 一个关于vue+mysql+express的全栈项目(三)------ 登录注册功能的实现(已经密码安全的设计)
本系列文章,主要是一个前端的视角来实现一些后端的功能,所以不会讲太多的前端东西,主要是分享做这个项目学到的一些东西,,,,, 好了闲话不多说,我们开始搭建后端服务,这里我们采用node的express ...
- STM32F407 NVIC 中断优先级管理 个人笔记
内嵌向量中断控制器:Nested Vectored Interrupt Controller (NVIC) 设置中断向量的优先级并使能. 响应优先级& 抢占优先级 抢占优先级:一个中断A还在处 ...
- Android View加载圆形图片且同时绘制圆形图片的外部边缘边线及边框:LayerDrawable实现
Android View加载圆形图片且同时绘制圆形图片的外部边缘边线及边框:LayerDrawable实现 LayerDrawable实现的结果和附录文章1,2,3中的layer-list一致. ...