POJ 1151 / HDU 1542 Atlantis 线段树求矩形面积并
题意:给出矩形两对角点坐标,求矩形面积并。
解法:线段树+离散化。
每加入一个矩形,将两个y值加入yy数组以待离散化,将左边界cover值置为1,右边界置为2,离散后建立的线段树其实是以y值建的树,线段树维护两个值:cover和len,cover表示该线段区间目前被覆盖的线段数目,len表示当前已覆盖的线段长度(化为离散前的真值),每次加入一条线段,将其y_low,y_high之间的区间染上line[i].cover,再以tree[1].len乘以接下来的线段的x坐标减去当前x坐标,即计算了一部分面积。
如图情况,将会计算三次面积:

代码:
#include <iostream>
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define eps 1e-8
using namespace std;
#define N 307 struct node
{
int cov;
double len;
}tree[*N]; struct Line
{
double y1,y2,x;
int cov;
}line[*N];
double yy[*N]; int cmp(Line ka,Line kb)
{
return ka.x < kb.x;
} int bsearch(int l,int r,double x)
{
while(l <= r)
{
int mid = (l+r)/;
if(fabs(yy[mid]-x) < eps)
return mid;
if(x > yy[mid])
l = mid+;
else
r = mid-;
}
return l;
} void build(int l,int r,int rt)
{
tree[rt].cov = ;
tree[rt].len = ;
if(l == r-) return;
int mid = (l+r)/;
build(l,mid,*rt);
build(mid,r,*rt+);
} void pushup(int l,int r,int rt)
{
if(tree[rt].cov)
tree[rt].len = yy[r]-yy[l];
else if(l+ == r)
tree[rt].len = ;
else
tree[rt].len = tree[*rt].len + tree[*rt+].len;
} void update(int l,int r,int aa,int bb,int cover,int rt)
{
if(aa <= l && bb >= r)
{
tree[rt].cov += cover;
pushup(l,r,rt);
return;
}
if(l+ == r) return;
int mid = (l+r)/;
if(aa <= mid)
update(l,mid,aa,bb,cover,*rt);
if(bb > mid)
update(mid,r,aa,bb,cover,*rt+);
pushup(l,r,rt);
} int main()
{
int n,m,cs = ,i,j;
double x1,y1,x2,y2;
while(scanf("%d",&n)!=EOF && n)
{
m = ;
for(i=;i<n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
line[m].x = x1,line[m].y1 = y1,line[m].y2 = y2,line[m].cov = ,yy[m++] = y1;
line[m].x = x2,line[m].y1 = y1,line[m].y2 = y2,line[m].cov = -,yy[m++] = y2;
}
m--;
sort(yy+,yy+m+);
int cnt = ;
for(i=;i<=m;i++)
{
if(yy[i] != yy[i-])
yy[cnt++] = yy[i];
}
cnt--;
build(,cnt,);
sort(line+,line+m+,cmp);
double ans = 0.0;
printf("Test case #%d\n",cs++);
for(i=;i<m;i++)
{
int L = bsearch(,cnt,line[i].y1);
int R = bsearch(,cnt,line[i].y2);
update(,cnt,L,R,line[i].cov,);
ans += tree[].len*(line[i+].x-line[i].x);
}
printf("Total explored area: %0.2lf\n\n",ans);
}
return ;
}
POJ 1151 / HDU 1542 Atlantis 线段树求矩形面积并的更多相关文章
- POJ 1151 Atlantis 线段树求矩形面积并 方法详解
第一次做线段树扫描法的题,网搜各种讲解,发现大多数都讲得太过简洁,不是太容易理解.所以自己打算写一个详细的.看完必会o(∩_∩)o 顾名思义,扫描法就是用一根想象中的线扫过所有矩形,在写代码的过程中, ...
- HDU 1542.Atlantis-线段树求矩形面积并(离散化、扫描线/线段树)-贴模板
好久没写过博客了,这学期不是很有热情去写博客,写过的题也懒得写题解.现在来水一水博客,写一下若干年前的题目的题解. Atlantis Time Limit: 2000/1000 MS (Java/Ot ...
- HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)
链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...
- hdu 1542 Atlantis (线段树扫描线)
大意: 求矩形面积并. 枚举$x$坐标, 线段树维护$[y_1,y_2]$内的边是否被覆盖, 线段树维护边时需要将每条边挂在左端点上. #include <iostream> #inclu ...
- 【hdu1542】线段树求矩形面积并
分割线内容转载自http://hzwer.com/879.html ------------------------------------------------------------------ ...
- HDU 1542 - Atlantis - [线段树+扫描线]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...
- HDU 1542 Atlantis(线段树面积并)
描述 There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. S ...
- POJ 1151 HDU 1542 Atlantis(扫描线)
题目大意就是:去一个地方探险,然后给你一些地图描写叙述这个地方,每一个描写叙述是一个矩形的右下角和左上角.地图有些地方是重叠的.所以让你求出被描写叙述的地方的总面积. 扫描线的第一道题,想了又想,啸爷 ...
- hdu 1542 Atlantis(线段树,扫描线)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
随机推荐
- 初学Java9:学习Mybatis时报错:Parameter 'name' not found. Available parameters are [1, 0, param1, param2]
报错-->Parameter 'name' not found. Available parameters are [1, 0, param1, param2] 百度找到这篇文章完成修改 htt ...
- httpclient 认证方式访问http api/resutful api并获取json结果
最近,因公司线上环境rabbitmq经常发生堆积严重的现象,于是跟运维组讨论,帮助开发个集中监控所有rabbitmq服务器运行情况的应用,需要通过java访问rabbitmq暴露的http api并接 ...
- jquery实现页面控件拖动效果js代码
;(function($) { var DragPanelId = "divContext"; var _idiffx = 0; var _idiffy = 0; var _Div ...
- SAP数据更新的触发
SAP 应用系统架构 应用层运行着DIALOG进程,每个DIALOG进程绑定一个数据库进程,DIALOG进程与GUI进行通信,每次GUI向应用服务器发送请求时都会通过dispatche ...
- SharePoint 新特性及安装需知
以下内容转自Kaneboy 大牛,但我在安装正式版的过程中发现一些问题,主要是.net 版本的问题,弄了我一个晚上,我在下面标出来了.我的安装环境是Windows server 2012 R2 关于详 ...
- Android项目实战(十六):QQ空间实现(一)—— 展示说说中的评论内容并有相应点击事件
大家都玩QQ空间客户端,对于每一个说说,我们都可以评论,那么,对于某一条评论: 白雪公主 回复 小矮人 : 你们好啊~ 我们来分析一下: .QQ空间允许我们 点击 回复人和被回复人的名字就可以进入对于 ...
- 浅析LruCache原理
Android用LruCache来取代原来强引用和软引用实现内存缓存,因为据说自2.3以后Android将更频繁的调用GC,导致软引用缓存的数据极易被释放. LruCache使用一个LinkedHas ...
- IOS 登陆界面的简单编写(通过NSNotificationCenter)
在介绍内容的之前,先看一下实现结果. 通过细节可以发现,只有当手机号与密码都输入的情况登录按钮才会变亮.那么这是怎么实现的呢? 首先我们要知道,这种情况的发生的首要条件便是每时每刻都知道两个TextF ...
- Swift控制流
本文简单的介绍swift一些基本语法的使用,在本文中不会做更深的剖析,只提及一些语法的简单的使用,快速学会编写swift程序.高手请绕路走嘿嘿 常量与变量: swift中定义所有的变量使用var,定义 ...
- Tesseract-OCR 字符识别---样本训练 [转]
Tesseract是一个开源的OCR(Optical Character Recognition,光学字符识别)引擎,可以识别多种格式的图像文件并将其转换成文本,目前已支持60多种语言(包括中文). ...