P1429 平面最近点对(加强版)

题意

题目描述

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

输入输出格式

输入格式:

第一行:\(n\);\(2\leq n\leq 200000\)

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

输出格式:

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

输入输出样例

输入样例#1:

3
1 1
1 2
2 2

输出样例#1:

1.0000

说明

\(0\leq x,y\leq 10^9\)

思路

利用分治的方法实现。我们先把所有点按照横坐标排序,然后查询每一个区间的最近点对距离。假设当前查询的是\([l,r]\)区间的最近点对距离,那么这个区间的答案就在\([l,mid]\)区间的最近点对距离、\([mid+1,r]\)区间的最近点对距离、靠近中间的分别在两个区间中的一些点之间的距离中产生,我们主要考虑第三部分答案如何统计。

首先通过分治,我们已经求出了左右两区间的最近点对距离\(min\),接下来找到\([l,r]\)区间内横坐标与\(mid\)的横坐标相差不超过\(min\)的点,并将这些点两两匹配求出最近距离。这样能保证答案的正确性,但是时间复杂度呢?据说这样子做的时间复杂度是\(O(n\log n)\)的,所以也不用担心超时的问题。

AC代码

#include<bits/stdc++.h>
using namespace std;
int n;
struct Point
{
double x,y;
bool operator < (const Point &sjf){return x<sjf.x;}
}p[200005],q[200005];
double devide(int l,int r)
{
if(l==r) return DBL_MAX;
else if(l+1==r) return sqrt((p[l].x-p[r].x)*(p[l].x-p[r].x)+(p[l].y-p[r].y)*(p[l].y-p[r].y));
int mid=(l+r)>>1,cnt=0;
double d=min(devide(l,mid),devide(mid+1,r));
for(int i=l;i<=r;i++) if(fabs(p[i].x-p[mid].x)<=d) q[++cnt]=p[i];
for(int i=1;i<=cnt;i++)
for(int j=i+1;j<=cnt&&fabs(q[i].x-q[j].x)<=d;j++)
d=min(d,sqrt((q[i].x-q[j].x)*(q[i].x-q[j].x)+(q[i].y-q[j].y)*(q[i].y-q[j].y)));
return d;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
sort(p+1,p+n+1);
printf("%.4f",devide(1,n));
return 0;
}

Luogu P1429 平面最近点对(加强版)(分治)的更多相关文章

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

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

  2. P1429 平面最近点对[加强版] 随机化

    LINK:平面最近点对 加强版 有一种分治的做法 因为按照x排序分治再按y排序 可以证明每次一个只会和周边的六个点进行更新. 好像不算很难 这里给出一种随机化的做法. 前置知识是旋转坐标系 即以某个点 ...

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

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

  4. Luogu 1429 平面最近点对 | 平面分治

    Luogu 1429 平面最近点对 题目描述 给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的 输入输出格式 输入格式: 第一行:n:2≤n≤200000 ...

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

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

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

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

  7. 洛谷 P1429 平面最近点对(加强版) (分治模板题)

    题意:有\(n\)个点对,找到它们之间的最短距离. 题解:我们先对所有点对以\(x\)的大小进行排序,然后分治,每次左右二等分递归下去,当\(l+1=r\)的时候,我们计算一下距离直接返回给上一层,若 ...

  8. p1429 平面最近点对(加强版)

    传送门 分析 我们可以枚举每一个点算它的最近点 估价函数应该分为3种情况计算: 大于max,小于min,位于min和max之间 代码 #include<iostream> #include ...

  9. (洛谷 P1429 平面最近点对(加强版) || 洛谷 P1257 || Quoit Design HDU - 1007 ) && Raid POJ - 3714

    这个讲的好: https://phoenixzhao.github.io/%E6%B1%82%E6%9C%80%E8%BF%91%E5%AF%B9%E7%9A%84%E4%B8%89%E7%A7%8D ...

随机推荐

  1. 页面JS缓存问题解决方案

    .在jsp中加入头 <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> <META HTTP-EQUI ...

  2. 基于vue的环信基本实时通信功能

    本篇文章借鉴了一些资料,然后在这个基础上,我将环信的实现全部都集成在一个组件里面进行实现: https://blog.csdn.net/github_35631540/article/details/ ...

  3. 尚学linux课程---10、linux环境下安装python

    尚学linux课程---10.linux环境下安装python 一.总结 一句话总结: 直接在官网下载python的源码包即可,然后在linux下安装 linux下安装软件优先想到的的确是yum,但是 ...

  4. [Ceoi2016|BZOJ4936] Match

    哈希+分治+stack 题目: 给你一个由小写字母组成的字符串s,要你构造一个字典序最小的(认为左括号的字典序比右括号小)合法的括号 序列与这个字符串匹配,字符串和括号序列匹配定义为:首先长度必须相等 ...

  5. windows 内核下获取进程路径

    windows 内核下获取进程路径 思路:1):在EPROCESS结构中获取.此时要用到一个导出函数:PsGetProcessImageFileName,申明如下: NTSYSAPI UCHAR *  ...

  6. android-启动另外一个Activity

    启动另外一个Activity 在完成了上一节课的学习后,我们已经创建了一个带有text输入框和一个button的app. 在本课中,我们将在MainActivity类中添加SendButton的单击响 ...

  7. android ListView 获取点击的选项

    需要调用listView的setOnItemClickListener方法 重写OnItemClickListener类的onItemClick 方法,onItemClick 方法有三个参数 @Ove ...

  8. 创建vue项目及引入插件

    部署开发环境 安装淘宝镜像 npm install -g cnpm --registry=https://registry.npm.taobao.org 安装webpack cnpm install ...

  9. C++内存字节对齐规则

    为什么要进行内存对齐以及对齐规则 C/C++—— 内存字节对齐规则 C++内存字节对齐规则

  10. DuiLib学习笔记1.编译运行demo

    c++中皮肤问题比较麻烦,MFC自带的太难用.DirectUI界面库就比较强大了,之前像skin++之类的基于DirectUI收费昂贵.DuiLib是基于DirectUI的界面库,可以将用户界面和处理 ...