Picture POJ - 1177 线段树+离散化+扫描线 求交叉图像周长
参考 https://www.cnblogs.com/null00/archive/2012/04/22/2464876.html
#include <stdio.h>
#include <algorithm>
#define LEN 10000
using namespace std; struct Node
{
int left;
int right;
int count;//被覆盖次数
//所包含的区间数量,如三条[1,2],[2,3],[4,5]线段被覆盖,则line=2,因为 [1,2],[2,3]是连续的。
int line;//所包含的区间数量
int lbd;//左端点是否被覆盖 用来辅助对line的计算
int rbd;//右端点是否被覆盖
int m;//测度 ,即覆盖的区间长度,如[2,8]就为6
}node[LEN*];;
struct ScanLine
{
int x;
int y1;
int y2;
int flag;
}scan[LEN];;
int y[LEN];
void build(int l, int r, int i)
{
node[i].left = l;
node[i].right = r;
node[i].count = ;
node[i].m = ;
node[i].line = ;
if (r - l > )
{
int middle = (l + r)/;
build(l, middle, *i + );
build(middle, r, *i + );
}
}
//更新测度m
void update_m(int i)
{
if (node[i].count > )
node[i].m = y[node[i].right] - y[node[i].left];
else if (node[i].right - node[i].left == )
node[i].m = ;
else
{
node[i].m = node[*i + ].m + node[*i + ].m;
}
}
//更新line
void update_line(int i)
{
if (node[i].count > )
{
node[i].lbd = ;
node[i].rbd = ;
node[i].line = ;
}
else if (node[i].right - node[i].left == )
{
node[i].lbd = ;
node[i].rbd = ;
node[i].line = ;
}
else
{
node[i].lbd = node[*i + ].lbd;
node[i].rbd = node[*i + ].rbd;
node[i].line = node[*i + ].line + node[*i + ].line - node[*i + ].rbd*node[*i + ].lbd;
}
}
void insert(int l, int r, int i)
{
//在这里要取离散化之前的原值进行比较
if (y[node[i].left] >= l && y[node[i].right] <= r)
(node[i].count)++;
else if (node[i].right - node[i].left == )
return;
else
{
int middle = (node[i].left + node[i].right)/;
if (r <= y[middle])
insert(l, r, *i + );
else if (l >= y[middle])
insert(l, r, *i + );
else
{
insert(l, y[middle], *i + );
insert(y[middle], r, *i + );
}
}
update_m(i);
update_line(i);
} void remove(int l, int r, int i)
{
////在这里要取离散化之前的原值进行比较
if (y[node[i].left] >= l && y[node[i].right] <= r)
(node[i].count)--;
else if (node[i].right - node[i].left == )
return;
else
{
int middle = (node[i].left + node[i].right)/;
if (r <= y[middle])
remove(l, r, *i + );
else if (l >= y[middle])
remove(l, r, *i + );
else
{
remove(l, y[middle], *i + );
remove(y[middle], r, *i + );
}
}
update_m(i);
update_line(i);
} bool cmp(ScanLine line1,ScanLine line2)
{
if (line1.x == line2.x)
return line1.flag > line2.flag;
return (line1.x < line2.x);
} int main()
{
int n;
scanf("%d", &n);
int x1, y1, x2, y2;
int i = ;
while (n--)
{
scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
scan[i].x = x1;
scan[i].y1 = y1;
scan[i].y2 = y2;
scan[i].flag = ;
y[i++] = y1;
scan[i].x = x2;
scan[i].y1 = y1;
scan[i].y2 = y2;
scan[i].flag = ;
y[i++] = y2;
}
sort(y, y + i);
sort(scan, scan + i, cmp);
//y数组中不重复的个数
int unique_count = unique(y, y + i) - y;
//离散化,建立线段树
build(, unique_count - , );
int perimeter = ;
int now_m = ;
int now_line = ;
for (int j = ; j < i; j++)
{
if (scan[j].flag)
insert(scan[j].y1, scan[j].y2, );
else
remove(scan[j].y1, scan[j].y2, );
if (j >= )
perimeter += *now_line*(scan[j].x - scan[j-].x);
//要减去,因为一个边只能算一次,要减去上一次已经算过的边
perimeter += abs(node[].m - now_m);
now_m = node[].m;
now_line = node[].line;
}
printf("%d\n", perimeter);
return ;
}
Picture POJ - 1177 线段树+离散化+扫描线 求交叉图像周长的更多相关文章
- 【POJ 2482】 Stars in Your Window(线段树+离散化+扫描线)
[POJ 2482] Stars in Your Window(线段树+离散化+扫描线) Time Limit: 1000MS Memory Limit: 65536K Total Submiss ...
- hdu1542 矩形面积并(线段树+离散化+扫描线)
题意: 给你n个矩形,输入每个矩形的左上角坐标和右下角坐标. 然后求矩形的总面积.(矩形可能相交). 题解: 前言: 先说说做这道题的感受: 刚看到这道题顿时就懵逼了,几何 烂的渣渣.后来从网上搜题解 ...
- POJ 1177 Picture(线段树:扫描线求轮廓周长)
题目链接:http://poj.org/problem?id=1177 题目大意:若干个矩形,求这些矩形重叠形成的图形的轮廓周长. 解题思路:这里引用一下大牛的思路:kuangbin 总体思路: 1. ...
- POJ 1177/HDU 1828 picture 线段树+离散化+扫描线 轮廓周长计算
求n个图矩形放下来,有的重合有些重合一部分有些没重合,求最后总的不规则图型的轮廓长度. 我的做法是对x进行一遍扫描线,再对y做一遍同样的扫描线,相加即可.因为最后的轮廓必定是由不重合的线段长度组成的, ...
- POJ 1151Atlantis 矩形面积并[线段树 离散化 扫描线]
Atlantis Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 21734 Accepted: 8179 Descrip ...
- POJ - 1177 线段树
POJ - 1177 扫描线 这道题也算是一道扫描线的经典题目了. 只不过这道题是算周长,非常有意思的一道题.我们已经知道了,一般求面积并,是如何求的,现在我们要把扫描线进行改造一下,使得能算周长. ...
- poj 2528(线段树+离散化) 市长的海报
http://poj.org/problem?id=2528 题目大意是市长竞选要贴海报,给出墙的长度和依次张贴的海报的长度区间(参考题目给的图),问最后你能看见的海报有几张 就是有的先贴的海报可能会 ...
- POJ1151Atlantis 矩形面积并[线段树 离散化 扫描线]
Atlantis Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 21734 Accepted: 8179 Descrip ...
- poj 2528 线段树+离散化
题意:在墙上贴一堆海报(只看横坐标,可以抽象成一线段),新海报可以覆盖旧海报.求最后能看到多少张海报 sol:线段树成段更新.铺第i张海报的时候更新sg[i].x~sg[i].y这一段为i. 然而坐标 ...
随机推荐
- 一个支持 CodeFirst/DbFirst/ModelFirst 的数据库小工具
一个支持 CodeFirst/DbFirst/ModelFirst 的数据库小工具 Intro DbTool 是一个支持 CodeFirst/DbFirst/ModelFirst 的数据库小工具,原本 ...
- tomcat-windows10环境搭建
1.进入Tomcat官网Apache Tomcat® - Welcome! 2.根据操作系统选择合适的版本下载 zip用于windows操作系统, tar.gz用于unix和linux操作系统 Bin ...
- error C2662
原因:关于const的问题 具体错误:函数的参数列表中参数签名为const,但是却调用了该参数的非const的成员函数 例子: 即使我们知道NoConst()并不会改变类的data成员,编译器依旧会报 ...
- Pyinstaller 打包程序为可执行文件exe
Pyiinstaller打包 pyinstaller是python的一个第三方模块,使用它可以将pythnon程序打包为可执行文件,实现打包后的程序在没有python环境的机器上也可以运行.pyins ...
- Ikuai路由安装及简单配置 v1.0
第一部分:创建虚拟机: 1.点击创建新的虚拟机 2.选择自定义模式创建(选择经典模式会更友好一些),然后点击下一步 3.下图内容不用管,直接点击下一步: 4.这里是选择安装系统路径.在这里我们 ...
- GPU 版 TensorFlow failed to create cublas handle: CUBLAS_STATUS_ALLOC_FAILED
原因: 使用 GPU 版 TensorFlow ,并且在显卡高占用率的情况下(比如玩游戏)训练模型,要注意在初始化 Session 的时候为其分配固定数量的显存,否则可能会在开始训练的时候直接报错退出 ...
- vsftp管理用户
[root@localhost vsftpd]# cat auto_createftp.py #!/usr/bin/env python #_*_coding:utf-8_*_ #date:20180 ...
- Keras入门(六)模型训练实时可视化
在北京做某个项目的时候,客户要求能够对数据进行训练.预测,同时能导出模型,还有在页面上显示训练的进度.前面的几个要求都不难实现,但在页面上显示训练进度当时笔者并没有实现. 本文将会分享如何在K ...
- 惊讶!缓存刚Put再Get居然获取不到?
最近一直在老家远程办公,微信突然响了下,有同事说遇到了一个奇怪的问题,让我帮忙看下. 现象就是标题所说的缓存获取不到的问题,我一听感觉这个问题挺有意思的,决定一探究竟. 下面给出部分代码还原下案发现场 ...
- Qps从300到1500的优化过程
最近压测一项目,遇到的性能问题比较典型,过程记录下来,给大家做定位调优参考: 表象: 单接口负载测试,qps最高到300,响应时间200ms,应用cpu达到90%以上,8c机器,如下图,写到这里可能有 ...