计蒜客 17313 Overlapping Rectangles
来源:互联网 发布:淘宝主图点击率怎么看 编辑:程序博客网 时间:2024/06/11 05:55
Problem
nanti.jisuanke.com/t/17313
Reference
扫描线算法完全解析
矩形面积并、矩形面积交、矩形周长并(线段树、扫描线总结)
POJ1151(线段树+扫描线求矩形面积并)
算法总结:【线段树+扫描线】&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828)
Meaning
平面上有若干个矩形,可能有重叠,问总的面积是多少(重叠部分只算一次)
Analysis
这是扫描线求矩形面积并的裸题。
总的思路就是把几个重叠在一起的矩形所组成的多边形,切成一个个小矩形,分别统计答案。
以从下往上扫描为例(上图来自:poj 1151 Atlantis】线段树之扫描线(面积并))。关注矩形的上、下边,这些边(看作分界线)把平面分成若干个区间,每个区间都报包含一个切出来的小矩形。这个矩形的高,就是相邻两条分界线之间的距离,而底边长就是在当前扫描线(即上图红线)上的那些边并起来的长度(即处于红线上的矩形边的并),底乘高就是这块被切出来的小矩形的面积。
怎么统计扫描线上的总长度呢?用线段树。
在从下往上扫的过程中(扫描,其实就先是把所有矩形上、下边放到一起,按 y 轴坐标从低到高拍序,然后从低到高地遍历这些边,也即遍厉分界线),每遇到一条边,看它是上边还是下边。如果是下边,就把这条边“并”进总长里;上边则删掉这部分,即抵消到当初上边并进来的那部分。
这份代码里,线段树的叶子对应的是“点”,而不是“区间”,至少两个点才能夹出一个区间,所以当区间长度只有 2 的时候,不应再往下搜树。
也可以改写成叶子对应一个区间的写法。
Code
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 1000;struct seg{ int l, r; // 边的左、右边界坐标 int h; // 边的高度 int v; // 标记上下边:1 -> 下边,-1 -> 上边 seg(int _l = 0, int _r = 0, int _h = 0, int _v = 0): l(_l), r(_r), h(_h), v(_v) {} bool operator < (const seg &rhs) const { return h < rhs.h; }} s[N<<1];int x[N<<1], cnt[N<<3], len[N<<3];void pushup(int l, int r, int rt){ if(cnt[rt]) len[rt] = x[r] - x[l]; else if(l + 1 >= r) // 已是最小区间,没有子区间 len[rt] = 0; else len[rt] = len[rt<<1] + len[rt<<1|1];}void update(int ul, int ur, int v, int l, int r, int rt){ if(ul <= l && r <= ur) { cnt[rt] += v; pushup(l, r, rt); return; } int m = l + r >> 1; if(ul < m) // 等于的时候也是不需要的,因为一个点不是区间 update(ul, ur, v, l, m, rt<<1); if(ur > m) // 同样不取等号 update(ul, ur, v, m, r, rt<<1|1); // [m,r]!不是[m+1,r]! pushup(l, r, rt);}int main(){ int n; while(~scanf("%d", &n) && n) { for(int i = 0, xl, xr, yl, yr; i < n; ++i) { scanf("%d%d%d%d", &xl, &yl, &xr, &yr); // 下边是 1,表示并入 s[i] = seg(xl, xr, yl, 1); // 下边-1,表示删除 s[i+n] = seg(xl, xr, yr, -1); x[i] = xl; x[i+n] = xr; } n <<= 1; // 边从低到高排 sort(s, s + n); sort(x, x + n); memset(len, 0, sizeof len); memset(cnt, 0, sizeof cnt); int m = unique(x, x + n) - x, ans = 0; for(int i = 0, l, r; i < n - 1; ++i) { // 离散化横坐标 l = lower_bound(x, x + m, s[i].l) - x; r = lower_bound(x, x + m, s[i].r) - x; // 并入或删除边 update(l, r, s[i].v, 0, m, 1); // 加入小矩形面积 ans += len[1] * (s[i+1].h - s[i].h); } printf("%d\n", ans); } puts("*"); return 0;}
阅读全文
0 0
- 计蒜客 17313 Overlapping Rectangles
- Overlapping Rectangles
- Overlapping Rectangles
- ???Overlapping Rectangles
- OVERLAPPING RECTANGLES题解
- UVa 460 - Overlapping Rectangles
- Overlapping Rectangles(线段树,矩形面积并)
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 Overlapping Rectangles
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 F. Overlapping Rectangles(扫描线)
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 F. Overlapping Rectangles
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 F. Overlapping Rectangles
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛: F. Overlapping Rectangles(线段树)
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 Overlapping Rectangles
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛:Overlapping Rectangles
- 矩形面积并集,2017ICPC网络赛(南宁)Overlapping Rectangles
- 2017 icpc 南宁赛区 F.Overlapping Rectangles(重叠矩形的最大面积+线段树模板)
- 2017南宁网络赛F.Overlapping Rectangles(扫描线法+线段树)
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 F. Overlapping Rectangles(面积并)
- selenium之登录账号参数化-Map集合
- DirectX_11_游戏编程入门_1
- 关于给javascript对象添加、删除、修改对象的属性
- Maven pom.xml中的元素modules、parent、properties以及import
- OpenGL光照基础
- 计蒜客 17313 Overlapping Rectangles
- redis学习
- 接口简介
- Git使用小结(2)
- ZOJ 1011
- 使用servlet来实现表单的登录机制并用filter来进行过滤操作
- 安装openssh-server报Depends: openssh-client (= 1:6.6p1-2ubuntu2.8)错误
- 补昨日博客-使用putty登录Windows实现虚拟机中的系统的开机、关机、重启
- Android事件分发机制——从基础深入源码解析