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变量,记录上一次扫描的时候的长度,对于每次遇到扫描线统计答案的 ...
随机推荐
- Qt html 界面混合编程
Qt部分 项目文件.pro Qt += webenginewidgets webchannel 创建WebEngineView #include <QtWebEngineWidgets> ...
- LintCode-Search 2D Matrix II
Write an efficient algorithm that searches for a value in an m x n matrix, return the occurrence of ...
- 路由器开发板上的TTL线连接方法
手头有个MTK双频路由器的开发板,做工良好,但让人蛋疼的是,TTL线没有标注TX/RX/GND/VCC,这个小细节的缺失给使用带来了巨大麻烦. 网上搜了半天也没找到相关电路图,只好遍历测试找到正确 ...
- python pip和easy_install使用方式(转载)
easy_install 跟 pip 都是Python 的套件管理程式,有了它们,在使用 Python 开发程式的时候会带来不少方便. easy_install 和pip 有什麼不一样?据 pip 官 ...
- 在eclipse里的 flex 没有可视化的编辑
注:在4.7版本里去掉了可视化编辑器. 转自:http://3470973.blog.51cto.com/3460973/1135328 最近eclipse切换了一个工作空间,创建的flex项 ...
- Smarty插件简单开发
smarty的插件相当简单,你的网站经常会用到一些特定的Url或Controller或Action的路由地址的动态生成,通过smarty插件方式可以很轻松的实现. 在smarty/plugins目录下 ...
- spoj 375 Query on a tree(树链剖分,线段树)
Query on a tree Time Limit: 851MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Sub ...
- 'mysql' 不是内部或外部命令,也不是可运行的程序或批处理文件的解决办法
前言: 本文的解决方法来自http://www.cnblogs.com/xionghui/archive/2012/04/11/2442404.html --感谢! 问题描述:新电脑装mysql后在c ...
- [luogu 1880]石子合并
题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...
- Unit Test Generator