题目大意:有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(构造多边形)的更多相关文章

  1. Erasing Edges - SGU 136(构造多边形)

    题目大意:已知一个多边形上的每条边的中点,还原出来一个多边形. 分析:因为偶数是不固定的,所以可以为任意起点,奇数只有一个,可以所有中点加减算出来第一个点,然后就是简单的向量计算点的位置了...... ...

  2. SGU 128. Snake --- 暴力枚举+并查集+贪心+计算几何

    <传送门> 128. Snake time limit per test: 0.25 sec. memory limit per test: 4096 KB There are N poi ...

  3. SGU 128.Snake

    时间限制:0.25s 空间限制:4m 题意: 在一个平面坐标中有N个点,现在要你用这N个点构造一个闭合图形,这个图形要满足以下条件: 1.这个图形要是闭合的:          2.图形上的点只能是给 ...

  4. 【hihocoder 1257 Snake Carpet】构造

    2015北京区域赛现场赛第4题. 题面:http://media.hihocoder.com/contests/icpcbeijing2015/problems.pdf OJ链接:http://hih ...

  5. Deep Snake : 基于轮廓调整的SOTA实例分割方法,速度32.3fps | CVPR 2020

    论文提出基于轮廓的实例分割方法Deep snake,轮廓调整是个很不错的方向,引入循环卷积,不仅提升了性能还减少了计算量,保持了实时性,但是Deep snake的大体结构不够优雅,应该还有一些工作可以 ...

  6. Google 地图 API V3 之 叠加层

    Google官方教程: Google 地图 API V3 使用入门 Google 地图 API V3 针对移动设备进行开发 Google 地图 API V3 之事件 Google 地图 API V3 ...

  7. poj3502 恶心题

    巨恶心的一个题::>_<:: 题意:给出航班航线和大陆,找航线上距离大陆最远的某一点距离大陆边缘的距离 标准算法:二分答案,从大陆边界向外扩展,扩展出来的面积会覆盖航线.找出航线上最后被覆 ...

  8. 【高德地图API】从零开始学高德JS API(二)地图控件与插件——测距、圆形编辑器、鼠标工具、地图类型切换、鹰眼鱼骨

    原文:[高德地图API]从零开始学高德JS API(二)地图控件与插件——测距.圆形编辑器.鼠标工具.地图类型切换.鹰眼鱼骨 摘要:无论是控件还是插件,都是在一级API接口的基础上,进行二次开发,封装 ...

  9. Openssl编程--源码分析

    Openssl编程 赵春平 著 Email: forxy@126.com 第一章 基础知识 8 1.1 对称算法 8 1.2 摘要算法 9 1.3 公钥算法 9 1.4 回调函数 11 第二章 ope ...

随机推荐

  1. 3.SQL*Plus命令

    3.1SQL*Plus与数据库的交互 主要用来数据库查询和数据处理的工具. 3.2SQL*Plus运行环境设置 3.2.1SET命令概述 用户可以使用SET命令设置SQL*Plus的运行环境,SET命 ...

  2. CSS3实用方法小记 2016.03.16

    圆角边框: border-radius : 4px; box阴影: box-shadow : 5px 5px 3px #000 ; /* 参数分别为向右拓展距离,向下拓展距离,阴影宽度,颜色*/ 背景 ...

  3. Lucene5.x 中文 同义词

    查询好好多资料,英文同义词好好的,中文就不行,多谢网友支持,拼接了好多代码,然后修改了一些,不足之处,多谢指正. 直接上代码吧,在代码中了解怎么分词的最好 1,创建分词引擎 public interf ...

  4. 最小生成树之 prim算法和kruskal算法(以 hdu 1863为例)

    最小生成树的性质 MST性质:设G = (V,E)是连通带权图,U是V的真子集.如果(u,v)∈E,且u∈U,v∈V-U,且在所有这样的边中, (u,v)的权c[u][v]最小,那么一定存在G的一棵最 ...

  5. ACM HDU 2044 一只小蜜蜂

    Problem Description 有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行.请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数. 其中,蜂房的结构如下所示. Input 输入数据的第一 ...

  6. LINUX命令行操作

    Linux 命令行快捷键 7条回复 涉及在linux命令行下进行快速移动光标.命令编辑.编辑后执行历史命令.Bang(!)命令.控制命令等.让basher更有效率. 说明 Ctrl – k: 先按住 ...

  7. php函数的初步使用

    通过调用函数,实现打印半金字塔.全金字塔.空心金字塔.菱形.空心菱形 调用例程 huaTuMain.php 被调用函数 huaTu.php

  8. Ext.Array 方法

    1. Ext.Array.clean(arr); 过滤数组中的空元素 var arr = [1,"",2,"",3]; Ext.clean(arr); // [ ...

  9. php中foreach()函数与Array数组经典案例讲解

    //php中foreach()函数与Array数组经典案例讲解 function getVal($v) { return $v; //可以加任意检查代码,列入要求$v必须是数字,或过滤非法字符串等.} ...

  10. PHP之路——Redis安装

    windows: redis下载链接:https://github.com/ServiceStack/redis-windows 然后编辑redis.windows.conf文件,我看网上有的教程说编 ...