POJ1177(扫描线求周长并)
题意:。。求周长并。。。
解析:参考求面积并
图借鉴自:https://www.cnblogs.com/shuaiwhu/archive/2012/04/22/2464876.html

自下而上扫描 首先 加GH 接着 加 Node[1].numseg * 2 *(Edge[i+1].y - Edge[i].y)即两条竖边 然后 加 BD 但这时要减去GH 因为 LN = GH 重复加了一次
依次推理
与面积并不同的是 最上面的边不要忘了加上。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = , INF = 0x7fffffff;
int X[maxn]; struct node{
int l, r, w; // l 和 r 分别为线段树的左右端点 w记录边重叠的情况
int numseg; // 记录竖边的对数
int lx, rx, sum; // sum代表当前区间线段的长度,lx和rx为线段的真实端点
bool lcover, rcover; // 标记当前区间的左右端点 与 numseg有关
}Node[maxn*]; struct edge{ // 存边
int lxx, rxx, y;
int f;
}Edge[maxn]; int cmp(edge a, edge b)
{
return a.y < b.y;
} void build(int k, int ll, int rr)
{
Node[k].l = ll, Node[k].r = rr;
Node[k].lx = X[ll];
Node[k].rx = X[rr];
Node[k].w = Node[k].numseg = , Node[k].sum = ;
Node[k].lcover = Node[k].rcover = false;
if(ll + == rr) return;
int m = (ll + rr) / ;
build(k*, ll, m);
build(k*+, m, rr);
} void down(int k)
{
if(Node[k].w > )
{
Node[k].sum = Node[k].rx - Node[k].lx;
Node[k].numseg = ;
Node[k].lcover = Node[k].rcover = true;
return;
}
if(Node[k].l + == Node[k].r)
{
Node[k].sum = ;
Node[k].numseg = ;
Node[k].lcover = Node[k].rcover = false;
}
else
{
Node[k].sum = Node[k*].sum + Node[k*+].sum;
Node[k].lcover = Node[k*].lcover, Node[k].rcover = Node[k*+].rcover;
Node[k].numseg = Node[k*].numseg + Node[k*+].numseg;
if(Node[k*].rcover && Node[k*+].lcover) Node[k].numseg--; //注意这里是左区间的右端点 和 右区间的左端点
}
} void update(int k, edge e)
{
if(Node[k].lx == e.lxx && Node[k].rx == e.rxx)
{
Node[k].w += e.f;
down(k);
return;
}
if(e.rxx <= Node[k*].rx) update(k*, e);
else if(e.lxx >= Node[k*+].lx) update(k*+, e);
else
{
edge temp = e;
temp.rxx = Node[k*].rx;
update(k*, temp);
temp = e;
temp.lxx = Node[k*+].lx;
update(k*+, temp);
}
down(k);
} int main()
{
int n, cnt = ;
scanf("%d",&n);
for(int i=; i<n; i++)
{
int x1, x2, y1, y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
Edge[++cnt].lxx = x1, Edge[cnt].rxx = x2, Edge[cnt].y = y1, Edge[cnt].f = ;
X[cnt] = x1;
Edge[++cnt].lxx = x1, Edge[cnt].rxx = x2, Edge[cnt].y = y2, Edge[cnt].f = -;
X[cnt] = x2;
}
sort(Edge+, Edge+cnt+, cmp);
sort(X+, X+cnt+);
int m = unique(X+, X+cnt+) - (X+);
build(, , m);
int ret = , last = ;
for(int i=; i<cnt; i++)
{
update(, Edge[i]);
ret += abs(Node[].sum - last); // 横边
ret += Node[].numseg * * (Edge[i+].y - Edge[i].y); // 加竖边
last = Node[].sum;
}
update(, Edge[cnt]);
ret += abs(Node[].sum - last); printf("%d\n",ret); return ;
}
POJ1177(扫描线求周长并)的更多相关文章
- N - Picture - poj 1177(扫描线求周长)
题意:求周长的,把矩形先进行融合后的周长,包括内周长 分析:刚看的时候感觉会跟棘手,让人无从下手,不过学过扫描线之后相信就很简单了吧(扫描线的模板- -),还是不说了,下面是一精确图,可以拿来调试数据 ...
- HDU 1828 Picture(线段树扫描线求周长)
Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- poj 1177 --- Picture(线段树+扫描线 求矩形并的周长)
题目链接 Description A number of rectangular posters, photographs and other pictures of the same shape a ...
- 扫描线矩形周长的并 POJ1177
//扫描线矩形周长的并 POJ1177 // 我是按x轴 #include <iostream> #include <cstdio> #include <cstdlib& ...
- HDU-1828 Picture(扫描线 求矩形并的周长)
http://acm.hdu.edu.cn/showproblem.php?pid=1828 Time Limit: 6000/2000 MS (Java/Others) Memory Limi ...
- hdu1828 Picture(线段树+扫描线+矩形周长)
看这篇博客前可以看一下扫描线求面积:线段树扫描线(一.Atlantis HDU - 1542(覆盖面积) 二.覆盖的面积 HDU - 1255(重叠两次的面积)) 解法一·:两次扫描线 如图我们可以 ...
- 编写一个Shape类,具有属性:周长和面积; 定义其子类三角形和矩形,分别具有求周长的方法。 定义主类E,在其main方法中创建三角形和矩形类的对象, 并赋给Shape类的对象a、b,使用对象a、b来测试其特性。
package shape; public class Shape { //定义成员变量 private double zhouchang; private double mianji; public ...
- C# 定积分求周长&面积原理 代码实现
前言: 前些日子,因为工作原因,接触到了求解曲线周长,真的是搞了很久,学生时代真的很简单,但是如今的我来说,忘记了....很多人跟我应该一样. 所以来巩固加强一下记忆.一开始的时候,求周长嘛,找公式呗 ...
- TZOJ 2569 Wooden Fence(凸包求周长)
描述 Did you ever wonder what happens to your money when you deposit them to a bank account? All banks ...
随机推荐
- 汇编指令:ldr和str,ldm和stm的区别
(1)LDR:L表示LOAD,LOAD的含义应该理解为:Load from memory into register.下面这条语句就说明的很清楚: LDR R1, [R2] R1<— ...
- Python学习总结 05 pandas
pandas官方网址 : http://pandas.pydata.org/ . pandas的安装比较复杂,如果想开箱即用,可以考虑下载WinPython.WinPython的官方地址是: htt ...
- .Net Core 系列之一 hello world
OS: win10 企业版 中文环境 .Net Core: 切记不要装64版本,否则可能会出现vs2017无法生成.net core 2.0的项目 dotnet-sdk-2.0.0-win-x86.e ...
- [Python]Python 使用 for 循环的小例子
[Python]Python 使用 for 循环的小例子: In [7]: for i in range(5): ...: print "xxxx" ...: print &quo ...
- Python 常用 代码片段
文件名字中含有特殊字符转成空格,因为?‘’等作为文件名是非法的.以下正则表达式进行过滤转换 newname = re.sub("[\s+\.\!\/_,$%^*(+\"\')]+| ...
- ubuntu16.04在GTX1070环境下安装 cuda9.1
设备要求 系统:Ubuntu16.04 显卡:GTX 1070 驱动:nvidia系列,显卡驱动的版本必须大于等于cuda的sh文件名里面的版本号 驱动可从 此处 下载,我已经整理好了 检查安装驱动 ...
- JSP中properties文件的路径问题
做练习的时候,写了个properties文件,放在src/servlet/目录下,访问文件问题花了点时间折腾,最终得到解决,记下. 环境:eclipse jee oxygen,tomcat 9.0. ...
- Java7和8在虚拟机上的差异:Perm Generation vs. Metaspace
- redux的源码解析
一. redux出现的动机 1. Javascript 需要管理比任何时候都要多的state2. state 在什么时候,由于什么原因,如何变化已然不受控制.3. 来自前端开发领域的新需求4. 我们总 ...
- 如何自定义一个组件loading
使用时需要Vue.use()一下