Luogu 1429 平面最近点对

题目描述

给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的

输入输出格式

输入格式:

第一行:n;2≤n≤200000

接下来n行:每行两个实数:x y,表示一个点的行坐标和列坐标,中间用一个空格隔开。

输出格式:

仅一行,一个实数,表示最短距离,精确到小数点后面4位。

这是一道平面上的分治。

这是一个平面,我们把它分成两半,使x坐标位于最中间的两个点分到左右两侧:

对于同在左侧或同在右侧的点对,我们可以递归处理;对于分别位于两侧的点对,如何处理呢?

设递归处理后我们知道同在左侧和同在右侧的点对中,最小距离是d;那么需要枚举的“分别位于两侧的点对”的两个端点的横坐标一定都位于中线左/右距离不超过d的范围内。

当枚举左侧的一个点的时候,右侧只需要找y坐标更小,且y坐标相差不超过d的点,与左侧的点配对。

有了以上两条限制,对于一个点p,另一侧需要与它配对的点不超过6个。

至于具体实现,要先把所有点按照x坐标排序,然后再递归的过程中按照y坐标排序。子区间内部点的顺序被修改(从按x排序变成按y排序),并不会影响母区间的划分,因为在递归进入子区间前母区间已经划分好了。

AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define space putchar(' ')
#define enter putchar('\n')
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
template <class T>
void read(T &x){
char c;
bool op = 0;
while(c = getchar(), c < '0' || c > '9')
if(c == '-') op = 1;
x = c - '0';
while(c = getchar(), c >= '0' && c <= '9')
x = x * 10 + c - '0';
if(op) x = -x;
}
template <class T>
void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar('0' + x % 10);
} const int N = 200005;
int n;
struct point {
double x, y;
point operator - (const point &b){
return (point){x - b.x, y - b.y};
}
double norm(){
return sqrt(x * x + y * y);
}
bool operator < (const point &b) const{
return x < b.x;
}
} p[N], a[N], b[N], c[N]; double solve(int l, int r){
if(l >= r) return 1e20;
int mid = (l + r) >> 1;
double xmid = (p[mid].x + p[mid + 1].x) / 2;
double d = min(solve(l, mid), solve(mid + 1, r));
int pos = l, pb = 0, pc = 0, pl = l, pr = mid + 1;
while(pos <= r){
if(pl <= mid && (pr > r || p[pl].y < p[pr].y)){
if(p[pl].x > xmid - d) b[++pb] = p[pl];
a[pos++] = p[pl++];
}
else{
if(p[pr].x < xmid + d) c[++pc] = p[pr];
a[pos++] = p[pr++];
}
}
for(int i = l; i <= r; i++) a[i] = p[i];
for(int i = 1, j = 1; i <= pb || j <= pc;){
if(i <= pb && (j > pc || b[i].y < c[j].y)){
for(int k = j - 1; k && b[i].y - c[k].y < d; k--)
d = min(d, (b[i] - c[k]).norm());
i++;
}
else{
for(int k = i - 1; k && c[j].y - b[k].y < d; k--)
d = min(d, (c[j] - b[k]).norm());
j++;
}
}
return d;
} int main(){ read(n);
for(int i = 1; i <= n; i++)
scanf("%lf%lf", &p[i].x, &p[i].y);
sort(p + 1, p + n + 1);
printf("%.4lf\n", solve(1, n)); return 0;
}

Luogu 1429 平面最近点对 | 平面分治的更多相关文章

  1. Vijos 1012 清帝之惑之雍正 平面最近点对(分治)

    背景 雍正帝胤祯,生于康熙十七年(1678)是康熙的第四子.康熙61年,45岁的胤祯继承帝位,在位13年,死于圆明园.庙号世宗. 胤祯是在康乾盛世前期--康熙末年社会出现停滞的形式下登上历史舞台的.复 ...

  2. 计算几何 平面最近点对 nlogn分治算法 求平面中距离最近的两点

    平面最近点对,即平面中距离最近的两点 分治算法: int SOLVE(int left,int right)//求解点集中区间[left,right]中的最近点对 { double ans; //an ...

  3. Luogu P1429 平面最近点对 【分治】By cellur925

    题目传送门 题目大意:给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的.$n$<=100000. $Algorithm$ 最朴素的$n^2$枚举肯定 ...

  4. 『Raid 平面最近点对』

    平面最近点对 平面最近点对算是一个经典的问题了,虽然谈不上是什么专门的算法,但是拿出问题模型好好分析一个是有必要的. 给定\(n\)个二元组\((x,y)\),代表同一平面内的\(n\)个点的坐标,求 ...

  5. Luogu4423 BJWC2011 最小三角形 平面最近点对

    传送门 题意:给出$N$个点,求其中周长最小的三角形(共线的也计算在内).$N \leq 2 \times 10^5$ 这道题唤起了我对平面最近点对的依稀记忆 考虑平面最近点对的分治,将分界线两边的求 ...

  6. Luogu P1429 平面最近点对(加强版)(分治)

    P1429 平面最近点对(加强版) 题意 题目描述 给定平面上\(n\)个点,找出其中的一对点的距离,使得在这\(n\)个点的所有点对中,该距离为所有点对中最小的. 输入输出格式 输入格式: 第一行: ...

  7. 平面最近点对(分治nlogn)

    平面最近点对,是指给出平面上的n个点,寻找点对间的最小距离 首先可以对按照x为第一关键字排序,然后每次按照x进行分治,左边求出一个最短距离d1,右边也求出一个最短距离d2,那么取d=min(d1, d ...

  8. P1429 平面最近点对(加强版)(分治)

    P1429 平面最近点对(加强版) 主要思路: 分治,将点按横坐标为第1关键字升序排列,纵坐标为第2关键字升序排列,进入左半边和右半边进行分治. 设d为左右半边的最小点对值.然后以mid这个点为中心, ...

  9. poj3714 Raid(分治求平面最近点对)

    题目链接:https://vjudge.net/problem/POJ-3714 题意:给定两个点集,求最短距离. 思路:在平面最近点对基础上加了个条件,我么不访用f做标记,集合1的f为1,集合2的f ...

随机推荐

  1. Laya资源加载小记

    Laya.Loader负责资源的加载逻辑,被LoaderManager管理. Laya支持多种类型资源加载,也支持自定义类型加载.不同类型的加载方式可能不同. Laya.Loader缓存已经被加载过得 ...

  2. 廖雪峰git教程学习笔记2

    本地git仓库和github仓库之间的传输是通过SSH加密的,所以: 注册GitHub账号 创建SSH key.在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id ...

  3. vue 动画

    Vue 在插入.更新或者移除 DOM 时,提供多种不同方式的应用过渡效果.包括以下几种常见的方式: 在 CSS 过渡和动画中自动应用 class 可以配合使用第三方 CSS 动画库,如 Animate ...

  4. dstat 性能测试工具常用选项

    dstat常用的选项有: -c     显示cpu使用情况 -d     显示磁盘使用情况 -g,     显示页面数据 -i      启用中断数据 -l      平均负载统计(1分钟,5分钟,1 ...

  5. SMR解析

    SMR描述 SMR(Shingled Magnetic Recording)叠瓦式磁记录盘是一种采用新型磁存储技术的高容量磁盘.SMR盘将盘片上的数据磁道部分重叠,就像屋顶上的瓦片一样,这种技术被称为 ...

  6. Centos7.2构建Python3.6开发环境

    1.安装python3.6 1.这里使用一台全新的腾讯云主机,首先获取linux系统版本信息. [root@VM_46_121_centos ~]# cat /etc/redhat-release C ...

  7. 深入理解JavaScript函数参数

    前面的话 javascript函数的参数与大多数其他语言的函数的参数有所不同.函数不介意传递进来多少个参数,也不在乎传进来的参数是什么数据类型,甚至可以不传参数. arguments javascri ...

  8. HDFS handler

    http://docs.oracle.com/goldengate/bd1221/gg-bd/GADBD/GUID-85A82B2E-CD51-463A-8674-3D686C3C0EC0.htm#G ...

  9. Scrum Meeting 10.24

    成员 已完成任务 下一阶段任务 用时 徐越 阅读后端代码,了解服务器的概念,以及服务器和终端间的通信机制 学习服务器配置 4h 赵庶宏 阅读后端代码,了解服务器的概念,以及服务器和终端间的通信机制 阅 ...

  10. 2017-2018-2 1723 『Java程序设计』课程 结对编程练习_四则运算

    一.结对对象 姓名:侯泽洋 学号:20172308 担任角色:驾驶员(侯泽洋) 伙伴第一周博客地址 二.本周内容 1.程序需求 (1).自动生成题目 可独立使用(能实现自己编写测试类单独生成题目的功能 ...