poj 1151 Atlantis (离散化 + 扫描线 + 线段树 矩形面积并)
题目链接
题意:给定n个矩形,求面积并,分别给矩形左上角的坐标和右上角的坐标。
分析:
映射到y轴,并且记录下每个的y坐标,并对y坐标进行离散。
然后按照x从左向右扫描。
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define LL __int64
#define lson l, mid, 2*rt
#define rson mid+1, r, 2*rt+1
const int maxn = +;
using namespace std;
int n;
double y[maxn];
struct node
{
int l, r, c; //l, r记录左右节点,c记录覆盖情况
double cnt, lf, rf; //cnt记录这一段当前的长度,lf,rf记录这一段实际的边界
}tr[*maxn];
struct Line
{
double x, y1, y2; //x记录该段x坐标,y1,y2记录该段投影的y边界
int f;
}line[maxn]; //记录在y轴上的投影,f=1表示线段的开始,f=-1表示线段的结束
bool cmp(Line a, Line b)
{
return a.x < b.x;
}
void build(int l, int r, int rt)
{
tr[rt].l = l; tr[rt].r = r;
tr[rt].cnt = tr[rt].c = ;
tr[rt].lf = y[l]; tr[rt].rf = y[r]; //相当于离散化,把实际左右坐标离散成l,r
if(l+==r) return;
int mid = (l+r)/;
build(l, mid, *rt);
build(mid, r, *rt+); //注意是mid,不是mid+1,因为要所有段覆盖
}
void calen(int rt)
{
if(tr[rt].c>) //如果这段被覆盖,就更新这段的长度为实际长度
{
tr[rt].cnt = tr[rt].rf-tr[rt].lf;
return;
}
if(tr[rt].l+==tr[rt].r) tr[rt].cnt = ; //如果这段被撤销,而且是最后的就把长度变为0
else tr[rt].cnt = tr[*rt].cnt+tr[*rt+].cnt; //如果被撤销但不是最后的,就加一下左右
}
void update(int rt, Line e) //加入或者减去一条线段后的更新
{
if(e.y1==tr[rt].lf && e.y2==tr[rt].rf)
{
tr[rt].c += e.f; //改变覆盖情况
calen(rt);
return;
}
if(e.y2<=tr[*rt].rf) update(*rt, e);
else if(e.y1>=tr[*rt+].lf) update(*rt+, e);
else //跨区间的情况
{
Line tmp = e;
tmp.y2 = tr[*rt].rf;
update(*rt, tmp);
tmp = e;
tmp.y1 = tr[*rt+].lf;
update(*rt+, tmp);
}
calen(rt);
}
int main()
{
int i, ca=, cnt;
double x1, x2, y1, y2, ans;
while(~scanf("%d", &n)&&n)
{
cnt = ; ans = ;
for(i = ; i < n; i++)
{
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
line[cnt].x = x1; line[cnt].y1 = y1;
line[cnt].y2 = y2; line[cnt].f = ;
y[cnt++] = y1;
line[cnt].x = x2; line[cnt].y1 = y1;
line[cnt].y2 = y2; line[cnt].f = -;
y[cnt++] = y2;
}
cnt--;
sort(line+, line+cnt+, cmp); //按x从小到大排序
sort(y+, y+cnt+); //按照y排序
build(, cnt, ); update(, line[]);
for(i = ; i <= cnt; i++)
{
ans += tr[].cnt*(line[i].x-line[i-].x); //tr[1].cnt记录全段中当前覆盖的值
update(, line[i]);
}
printf("Test case #%d\n", ca++);
printf("Total explored area: %.2lf\n\n", ans);
}
return ;
}
poj 1151 Atlantis (离散化 + 扫描线 + 线段树 矩形面积并)的更多相关文章
- HDU 1542:Atlantis(扫描线+线段树 矩形面积并)***
题目链接 题意 给出n个矩形,求面积并. 思路 使用扫描线,我这里离散化y轴,按照x坐标从左往右扫过去.离散化后的y轴可以用线段树维护整个y上面的线段总长度,当碰到扫描线的时候,就可以统计面积.这里要 ...
- hdu1542(线段树——矩形面积并)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 分析:离散化+扫描线+线段树 #pragma comment(linker,"/STA ...
- hdu1542 Atlantis(扫描线+线段树+离散)矩形相交面积
题目链接:点击打开链接 题目描写叙述:给定一些矩形,求这些矩形的总面积.假设有重叠.仅仅算一次 解题思路:扫描线+线段树+离散(代码从上往下扫描) 代码: #include<cstdio> ...
- POJ_3470 Walls 【离散化+扫描线+线段树】
一.题面 POJ3470 二.分析 POJ感觉是真的老了. 这题需要一些预备知识:扫描线,离散化,线段树.线段树是解题的关键,因为这里充分利用了线段树区间修改的高效性,再加上一个单点查询. 为什么需要 ...
- HDU 3265/POJ 3832 Posters(扫描线+线段树)(2009 Asia Ningbo Regional)
Description Ted has a new house with a huge window. In this big summer, Ted decides to decorate the ...
- ACM学习历程—POJ1151 Atlantis(扫描线 && 线段树)
Description There are several ancient Greek texts that contain descriptions of the fabled island Atl ...
- Poj1151&HDU1542 Atlantis(扫描线+线段树)
题意 给定\(n\)个矩形\((x_1,y_1,x_2,y_2)\),求这\(n\)个矩形的面积并 题解 扫描线裸题,可以不用线段树维护,\(O(n^2)\)是允许的. #include < ...
- hdu 4419 Colourful Rectangle (离散化扫描线线段树)
Problem - 4419 题意不难,红绿蓝三种颜色覆盖在平面上,不同颜色的区域相交会产生新的颜色,求每一种颜色的面积大小. 比较明显,这题要从矩形面积并的方向出发.如果做过矩形面积并的题,用线段树 ...
- HDU 1828:Picture(扫描线+线段树 矩形周长并)
题目链接 题意 给出n个矩形,求周长并. 思路 学了区间并,比较容易想到周长并. 我是对x方向和y方向分别做两次扫描线.应该记录一个pre变量,记录上一次扫描的时候的长度,对于每次遇到扫描线统计答案的 ...
随机推荐
- SharePoint 2010 的企业级搜索技术文章
http://msdn.microsoft.com/zh-cn/library/ff828776(v=office.14).aspx http://msdn.microsoft.com/zh-cn/l ...
- Notes of the scrum meeting(11/1)
meeting time:9:00~10:30p.m.,November 1st,2013 meeting place:20号公寓楼前 attendees: 顾育豪 ...
- KVM通过qemu实现USB重定向
KVM是通过qemu来支持USB设备的,可以在启动的时候就指定需要连接的USB设备,也可以系统启动后动态的添加删除.通过qemu的help可知,使用qemu的usb_add host:xxx:xxx来 ...
- 面试问到:JDBC、hibernate、ibati
一.JDBC.Connection(连接) 优点:运行高效.快捷. 缺点:代码多.异常多.不支持跨平台. 二.ibatis 1.根据jdbc的基本建立连接. 2.通过anntation+xml.jav ...
- c语言编程之循环队列
利用链表实现的循环队列,完成了队列的入队和出队,对于队空和队满用了一个flag进行标记.入队flag++,出队flag-- #include"stdio.h" typedef in ...
- Halcon学习笔记之缺陷检测(二)
例程:detect_indent_fft.hdev 说明:这个程序展示了如何利用快速傅里叶变换(FFT)对塑料制品的表面进行目标(缺陷)的检测,大致分为三步: 首先,我们用高斯滤波器构造一个合适的滤波 ...
- java集合类(四)About Set
接上篇:java集合类(三)About Iterator & Vector(Stack) 之前,在比较java常见集合类的时候,就了解到一点有关Set的特性.实现类及其要求等,读者可以去温习下 ...
- BZOJ 1051: [HAOI2006]受欢迎的牛 强连通缩点
题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=1051 题解: 强连通缩点得到DAG图,将图转置一下,对入度为零的点跑dfs看看能不能访问 ...
- HDAO
dx11 hdao10.1 除了dx的sample竟然搜不到什么文档.... 估计去问别人也是让我继续看代码.. ---------------------------------------- 算法 ...
- POJ 2771 Guardian of Decency(求最大点独立集)
该题反过来想:将所有可能发生恋爱关系的男女配对,那么可以带出去的人数应该等于这个二分图的最大独立集 先要做一下预处理,把不符合要求的双方先求出来, company[i][j]表示i.j四个标准都不符合 ...