HDU 1542 Atlantis(扫描线)题解
题意:给n个可能相交的矩形,问你不重复的总面积
思路:扫描线,一边扫一边加。
扫描线:图片来源:理解扫描线
假设我们要算以下四个矩形面积,显然中间深色的是重复的。我们按照x的大小,从左往右扫,然后用线段树维护y轴向的长度就可以了。但是,我们不能用点去维护y轴坐标,而是抽象成把点i看成y[i]到y[i+1]这个区间,不然会有错。
代码:
#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
typedef long longll;
using namespace std;
const int maxn = + ;
const int MOD = 1e9 + ;
const int INF = 0x3f3f3f3f;
struct Bian{
double x, y1, y2;
int flag;
bool operator < (const Bian &a) const{
return x < a.x;
}
}bian[maxn << ];
double y[maxn << ]; //离散化定位
int n, cnt;
int Find(double x){ //在y中离散化后位置
int l = , r = cnt, ans = ;
while(l <= r){
int m = (l + r) >> ;
if(fabs(y[m] - x) < 1e-) ans = m;
if(y[m] > x) r = m - ;
else l = m + ;
}
return ans;
}
int cover[maxn << ]; //y的覆盖次数
double sum[maxn << ];
void pushUp(int l, int r, int rt){
if(cover[rt] > ) sum[rt] = y[r + ] - y[l];
//全覆盖了
else if(l == r) sum[rt] = ;
//没覆盖的叶子结点
else sum[rt] = sum[rt << ] + sum[rt << | ];
//部分覆盖
}
void build(int l, int r, int rt){
if(l == r){
cover[rt] = sum[rt] = ;
return;
}
int m = (l + r) >> ;
build(l, m, rt << );
build(m + , r, rt << | );
cover[rt] = sum[rt] = ;
}
void update(int L, int R, int l, int r, int v, int rt){
if(L <= l && R >= r){
cover[rt] += v;
pushUp(l, r, rt);
return;
}
int m = (l + r) >> ;
if(L <= m)
update(L, R, l, m, v, rt << );
if(R > m)
update(L, R, m + , r, v, rt << | );
pushUp(l, r, rt);
}
int main(){
int ca = ;
while(scanf("%d", &n) && n){
for(int i = ; i <= n; i++){
double x1, x2, y1, y2;
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
int ll = * i - , rr = * i;
bian[ll].x = x1, bian[ll].y1 = y1, bian[ll].y2 = y2;
bian[ll].flag = ;
bian[rr].x = x2, bian[rr].y1 = y1, bian[rr].y2 = y2;
bian[rr].flag = -;
y[ll] = y1, y[rr] = y2; //定位用的
}
n = n + n;
sort(bian + , bian + n + );
sort(y + , y + n + ); cnt = ; //unique
for(int i = ; i <= n; i++){
if(y[i] != y[i - ]){
y[++cnt] = y[i];
}
} double ans = ;
build(, cnt, );
for(int i = ; i < n; i++){
update(Find(bian[i].y1), Find(bian[i].y2) - , , cnt, bian[i].flag, );
ans += sum[] * (bian[i + ].x - bian[i].x);
}
printf("Test case #%d\n", ca++);
printf("Total explored area: %.2lf\n\n", ans);
}
return ;
}
HDU 1542 Atlantis(扫描线)题解的更多相关文章
- POJ 1151 HDU 1542 Atlantis(扫描线)
题目大意就是:去一个地方探险,然后给你一些地图描写叙述这个地方,每一个描写叙述是一个矩形的右下角和左上角.地图有些地方是重叠的.所以让你求出被描写叙述的地方的总面积. 扫描线的第一道题,想了又想,啸爷 ...
- (HDU 1542) Atlantis 矩形面积并——扫描线
n个矩形,可以重叠,求面积并. n<=100: 暴力模拟扫描线.模拟赛大水题.(n^2) 甚至网上一种“分块”:分成n^2块,每一块看是否属于一个矩形. 甚至这个题就可以这么做. n<=1 ...
- HDU 1542 Atlantis(矩形面积并)
HDU 1542 Atlantis 题目链接 题意:给定一些矩形,求面积并 思路:利用扫描线,因为这题矩形个数不多,直接暴力扫就能够了.假设数据大.就要用线段树 代码: #include <cs ...
- HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 1542 - Atlantis - [线段树+扫描线]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...
- hdu 1542 Atlantis(线段树,扫描线)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- hdu 1542 Atlantis(段树&扫描线&面积和)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- (中等) HDU 1542 Atlantis,扫描线。
Problem Description There are several ancient Greek texts that contain descriptions of the fabled is ...
- HDU 1542 Atlantis (线段树 + 扫描线 + 离散化)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
随机推荐
- js自定义格式化时间戳的格式
题目为 : 写一个模块,外部调用这个模块,请求参数是时间戳,模块要求 今天的时间,统一用24小时写作 03:00.15:04 昨天的时间,统一写昨天 昨天之前的时间,但在本周之内的时间,统一用周一.周 ...
- app启动过程
调用main函数之前: App开始启动后,系统首先加载可执行文件(自身App的所有.o文件的集合),然后加载动态链接库dyld.交由 ImageLoader 读取 image,其中包含了我们的类.方法 ...
- jeecg富文本编辑器增加字体(仿宋)
jeecg富文本编辑器增加字体(仿宋) 温馨提示:jeecg 提供了 uedit 富文本的实现,如下针对的是 uedit 增加仿宋字体示例. 主要修改三个文件:plug-in\ueditor\uedi ...
- 【SpringBoot】springboot -- 2.0版本自定义ReidsCacheManager的改变
1. 问题发现 在1.0版本中,我们配置redis的cacheManager是这种方式: //缓存管理器 @Bean public CacheManager cacheManager(@Suppres ...
- jupyter notebook 动态图显示
直接在import matplotlib.pyplot as plt 后面加%matplotlib,或者%matplotlib auto就可以通过弹出窗口的形式显示图片
- 移除Excel工作表密码保护小工具含C#源代码
有朋友发了个Excel.xlsx文件给我,让我帮忙看看里面是怎么做出来的.打开审阅后发现,每个Excel工作表都添加了密码保护: 看不到里面的隐藏列和公式等等,感觉很神秘.于是研究了一下Excel文件 ...
- 60.Vue:将px转化为rem,适配移动端
1.下载lib-flexible 我使用的是vue-cli+webpack,所以是通过npm来安装的 npm i lib-flexible --save 2.引入lib-flexible 在main. ...
- jquery的输入框自动补全功能+ajax
jquery的输入框自动补全功能+ajax 2017年05月10日 18:51:39 辣姐什么鬼 阅读数:1461 标签: web前端 更多 个人分类: web前端 内容参考网友文章写成,原博的链 ...
- 基于C#的Appium自动化测试框架(Ⅰ):程序结构
因为工作原因,使用的编程语言都是C#,但是国内相应的Appium资料少得可怜,Java版本的Appium也考虑过,但是奈何自己搞不定Eclipse这个编译环境[说白了就是因为懒…… 无意中看到了外面的 ...
- JSON 是个什么??!!!
json就是字符串! json就是字符串! json就是字符串! 重要的事情说三遍!json本质就是字符串,经过序列化的字符串.json的出现只是方便传输.你可以将所有的数据类型用序列化函数序列化js ...