Snake - SGU 128(构造多边形)
题目大意:有N个点,如果可以使用这N个点连接,连接的时候任意两条边要成直角,任意边都要平行于x轴或者y轴,并且不能出现跨立相交,最终组成一个闭合的多边形,求出来这个多边形的最小长度。
分析:容易证明这个多边形的存在是唯一的,因为每个点出发都会产生两条边,横着的或者竖着的,而且,相同x或者相同y的点所在的线上的点数要是偶数,否则无法分配,首先按照x点的值进行排序,那么就会得到平行于y轴的边,并且把这些相同的x值加入它所在的集合,用来判断与横轴的相交(可以使用二分查找的方式快速判断是否有相交边),然后按照y值排序得到平行于x轴的边,判断是否有相交情况即可,可以使用并查集判断图是否联通。
ps.错了N次,才发现原来做去重的时候没有排序.........,判断相交的时候也可以使用线段树,不过感觉略麻烦
代码如下:
====================================================================================================================================================
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
using namespace std; const int MAXN = ; struct point{int x, y, id;}p[MAXN];
struct segment{
point s, e;
segment(){}
segment(point s, point e):s(s),e(e){}
};
vector<segment>sg[MAXN];
int Hash[MAXN], Hn, father[MAXN]; bool cmp_point_x(point t1, point t2)
{
if(t1.x != t2.x)
return t1.x < t2.x;
return t1.y < t2.y;
}
bool cmp_point_y(point t1, point t2)
{
if(t1.y != t2.y)
return t1.y < t2.y;
return t1.x < t2.x;
}
bool QuickPow(int k, int e)
{
int L=, R = sg[k].size()-; while(L <= R)
{
int Mid = (L+R) >> ;
segment t = sg[k][Mid]; if(e > t.s.y && e < t.e.y)
return true;
if(e < t.s.y)
R = Mid - ;
else
L = Mid + ;
} return false;
}
int Find(int x)
{
if(x != father[x])
father[x] = Find(father[x]);
return father[x];
}
void Union(int u, int v)
{
u = Find(u), v = Find(v);
father[u] = v;
}
int main()
{
int N, ok=, len=; scanf("%d", &N); for(int i=; i<N; i++)
{
scanf("%d%d", &p[i].x, &p[i].y);
p[i].id = i;
Hash[i] = p[i].x;
father[i] = i;
} sort(p, p+N, cmp_point_x);///先按照x点进行排序
sort(Hash, Hash+N);
Hn = unique(Hash, Hash+N) - Hash; for(int i=; i<N; i+=)
{
if(i==N- || p[i].x != p[i+].x)
{
ok = ;
break;
} int k = lower_bound(Hash, Hash+Hn, p[i].x) - Hash;
sg[k].push_back(segment(p[i],p[i+]));
Union(p[i].id, p[i+].id);
len += p[i+].y - p[i].y;
} if(ok)
{///分列不成功
printf("0\n");
return ;
} sort(p, p+N, cmp_point_y); for(int i=; i<N; i+=)
{
if(i==N- || p[i].y != p[i+].y)
{
ok = ;
break;
}
Union(p[i].id, p[i+].id);
len += p[i+].x - p[i].x; int L = lower_bound(Hash, Hash+Hn, p[i].x) - Hash;
int R = lower_bound(Hash, Hash+Hn, p[i+].x) - Hash; for(int j=L+; j<R; j++)
{
ok = QuickPow(j, p[i].y);
if(ok)break;
} if(ok)break;
} int cnt = ;
for(int i=; i<N; i++)
{
if(father[i] == i)
cnt++;
if(cnt > )
{
ok = ;
break;
}
} if(ok)
printf("0\n");
else
printf("%d\n", len); return ;
}
Snake - SGU 128(构造多边形)的更多相关文章
- Erasing Edges - SGU 136(构造多边形)
题目大意:已知一个多边形上的每条边的中点,还原出来一个多边形. 分析:因为偶数是不固定的,所以可以为任意起点,奇数只有一个,可以所有中点加减算出来第一个点,然后就是简单的向量计算点的位置了...... ...
- SGU 128. Snake --- 暴力枚举+并查集+贪心+计算几何
<传送门> 128. Snake time limit per test: 0.25 sec. memory limit per test: 4096 KB There are N poi ...
- SGU 128.Snake
时间限制:0.25s 空间限制:4m 题意: 在一个平面坐标中有N个点,现在要你用这N个点构造一个闭合图形,这个图形要满足以下条件: 1.这个图形要是闭合的: 2.图形上的点只能是给 ...
- 【hihocoder 1257 Snake Carpet】构造
2015北京区域赛现场赛第4题. 题面:http://media.hihocoder.com/contests/icpcbeijing2015/problems.pdf OJ链接:http://hih ...
- Deep Snake : 基于轮廓调整的SOTA实例分割方法,速度32.3fps | CVPR 2020
论文提出基于轮廓的实例分割方法Deep snake,轮廓调整是个很不错的方向,引入循环卷积,不仅提升了性能还减少了计算量,保持了实时性,但是Deep snake的大体结构不够优雅,应该还有一些工作可以 ...
- Google 地图 API V3 之 叠加层
Google官方教程: Google 地图 API V3 使用入门 Google 地图 API V3 针对移动设备进行开发 Google 地图 API V3 之事件 Google 地图 API V3 ...
- poj3502 恶心题
巨恶心的一个题::>_<:: 题意:给出航班航线和大陆,找航线上距离大陆最远的某一点距离大陆边缘的距离 标准算法:二分答案,从大陆边界向外扩展,扩展出来的面积会覆盖航线.找出航线上最后被覆 ...
- 【高德地图API】从零开始学高德JS API(二)地图控件与插件——测距、圆形编辑器、鼠标工具、地图类型切换、鹰眼鱼骨
原文:[高德地图API]从零开始学高德JS API(二)地图控件与插件——测距.圆形编辑器.鼠标工具.地图类型切换.鹰眼鱼骨 摘要:无论是控件还是插件,都是在一级API接口的基础上,进行二次开发,封装 ...
- Openssl编程--源码分析
Openssl编程 赵春平 著 Email: forxy@126.com 第一章 基础知识 8 1.1 对称算法 8 1.2 摘要算法 9 1.3 公钥算法 9 1.4 回调函数 11 第二章 ope ...
随机推荐
- 3.SQL*Plus命令
3.1SQL*Plus与数据库的交互 主要用来数据库查询和数据处理的工具. 3.2SQL*Plus运行环境设置 3.2.1SET命令概述 用户可以使用SET命令设置SQL*Plus的运行环境,SET命 ...
- CSS3实用方法小记 2016.03.16
圆角边框: border-radius : 4px; box阴影: box-shadow : 5px 5px 3px #000 ; /* 参数分别为向右拓展距离,向下拓展距离,阴影宽度,颜色*/ 背景 ...
- Lucene5.x 中文 同义词
查询好好多资料,英文同义词好好的,中文就不行,多谢网友支持,拼接了好多代码,然后修改了一些,不足之处,多谢指正. 直接上代码吧,在代码中了解怎么分词的最好 1,创建分词引擎 public interf ...
- 最小生成树之 prim算法和kruskal算法(以 hdu 1863为例)
最小生成树的性质 MST性质:设G = (V,E)是连通带权图,U是V的真子集.如果(u,v)∈E,且u∈U,v∈V-U,且在所有这样的边中, (u,v)的权c[u][v]最小,那么一定存在G的一棵最 ...
- ACM HDU 2044 一只小蜜蜂
Problem Description 有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行.请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数. 其中,蜂房的结构如下所示. Input 输入数据的第一 ...
- LINUX命令行操作
Linux 命令行快捷键 7条回复 涉及在linux命令行下进行快速移动光标.命令编辑.编辑后执行历史命令.Bang(!)命令.控制命令等.让basher更有效率. 说明 Ctrl – k: 先按住 ...
- php函数的初步使用
通过调用函数,实现打印半金字塔.全金字塔.空心金字塔.菱形.空心菱形 调用例程 huaTuMain.php 被调用函数 huaTu.php
- Ext.Array 方法
1. Ext.Array.clean(arr); 过滤数组中的空元素 var arr = [1,"",2,"",3]; Ext.clean(arr); // [ ...
- php中foreach()函数与Array数组经典案例讲解
//php中foreach()函数与Array数组经典案例讲解 function getVal($v) { return $v; //可以加任意检查代码,列入要求$v必须是数字,或过滤非法字符串等.} ...
- PHP之路——Redis安装
windows: redis下载链接:https://github.com/ServiceStack/redis-windows 然后编辑redis.windows.conf文件,我看网上有的教程说编 ...