洛谷P1257 平面上的最接近点对
n<=10000个点,求欧几里德距离最小的一对点。
经典分治,把这些点按x排序,分成两半,每边分别算答案,答案是左边的最小,右边的最小,左右组起来的最小三者的最小。发现只有左右组的有点难写。
假设左右两半各自的最小中的最小是d,左半边最右的点横坐标是X1,右半边最左的点的横坐标是X2。那么只需要坐标在X1-d到X2+d的范围内的点找更小的距离。如下图。

极端地,x1和x2相等时,x1上的某一个点最多可能和多少点组更小的距离呢?

假如左半边上在x1上有一个大大的点,那么右半边的点只有在圆形区域内才可能组成更小距离。而由于右边的点的最小距离不小于d,因此涉及到圆形区域对应的纵坐标范围的点最多有:

这样六个点,也就是说,比如左边那个点纵坐标y,只要在右边找到纵坐标大于等于y的第一个点,然后用它上下的六个点来和左边那个点凑更短的距离即可。这样,只需要把两半横坐标符合的点装进两个数组里,按y排序,两个指针扫一次即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
//#include<iostream>
using namespace std; int n;
#define maxn 10011
struct Point
{
double x,y;
}p[maxn],a[maxn],b[maxn];int la=,lb=;
bool cmpx(const Point &a,const Point &b) {return a.x<b.x;}
bool cmpy(const Point &a,const Point &b) {return a.y<b.y;}
double sqr(double x) {return x*x;}
double dis(const Point &a,const Point &b)
{
return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
}
double merge(int L,int R)
{
if (L==R) return 1e18;
if (R-L==) return dis(p[L],p[R]);
const int mid=(L+R)>>;
double ans=min(merge(L,mid),merge(mid+,R));
la=lb=;
for (int i=L;i<=mid;i++) if (p[mid].x-p[i].x<=ans) a[++la].x=p[i].x,a[la].y=p[i].y;
for (int i=mid+;i<=R;i++) if (p[i].x-p[mid+].x<=ans) b[++lb].x=p[i].x,b[lb].y=p[i].y;
sort(a+,a++la,cmpy);sort(b+,b++lb,cmpy);
int j=;
for (int i=;i<=la;i++)
{
while (j<=lb && b[j].y<a[i].y) j++;
for (int k=max(,j-);k<=min(lb,j+);k++) ans=min(ans,dis(a[i],b[k]));
}
return ans;
}
int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
sort(p+,p++n,cmpx);
printf("%.4lf\n",merge(,n));
return ;
}
洛谷P1257 平面上的最接近点对的更多相关文章
- 洛谷 P1257 平面上的最接近点对 题解
P1257 平面上的最接近点对 题目描述 给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的. 输入格式 第一行:n:2≤n≤10000 接下来n行:每行两 ...
- P1257 平面上的最接近点对
题目描述 给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的 输入输出格式 输入格式: 第一行:n:2≤n≤200000 接下来n行:每行两个实数:x y, ...
- (洛谷 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 ...
- 洛谷 P6362 平面欧几里得最小生成树
题目描述 平面上有 \(n\) 个点,第 \(i\) 个点坐标为 \((x_i, y_i)\).连接 \(i, j\) 两点的边权为 \(\sqrt{(x_i - x_j) ^ 2 + (y_i - ...
- p1257 平面上最接近点对---(分治法)
首先就是一维最接近点的情况... #include<iostream> #include<cstdio> #include<cstring> #include< ...
- [洛谷 P2508] 圆上的整点
题目描述 求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数. 输入输出格式 输入格式: r 输出格式: 整点个数 输入输出样例 输入样例#1: 4 输出样例#1: 4 说明 n ...
- 洛谷 P2800 又上锁妖塔
https://www.luogu.org/problem/show?pid=2800 题目背景 小D在X星买完了想要的东西,在飞往下一个目的地的途中,正无聊的他转头看了看身边的小A,发现小A正在玩& ...
- 【洛谷P1726】上白泽慧音
上白泽慧音 题目链接 强联通分量模板题,Tarjan求强联通分量,记录大小即可 #include<iostream> #include<cstring> #include< ...
- 洛谷 P1952 火星上的加法运算_NOI导刊2009提高(3)
P1952 火星上的加法运算_NOI导刊2009提高(3) 题目描述 最近欢欢看到一本有关火星的书籍,其中她被一个加法运算所困惑,由于她的运算水平有限.她想向你求助,作为一位优秀的程序员,你当然不会拒 ...
随机推荐
- jmeter(二)元件的作用域与执行顺序
1.元件的作用域 JMeter中共有8类可被执行的元件(测试计划与线程组不属于元件),这些元件中,取样器是典型的不与其它元件发生交互作用的元件,逻辑控制器只对其子节点的取样器有效,而其它元件(conf ...
- 把sed当作命令解释器使用
[root@sishen ~]# vim script.sed #!/bin/sed -f #交换第一列和第二列 s/\([^,]*\),\([^,]*\),\(.*\).*/\2,\1, \3/g ...
- office doc/xls/ppt 和 docx/xlsx/pptx 区别
经同事告诉,今天才真正明白两都区别: doc/xls/ppt 是office2007以前的扩展名: docx/xlsx/pptx 是office2007版本及以后的扩展名,是基于xml的文件格式,x ...
- 配置Oracle监听器
Oracle的监听和网络服务都可以在Net Manager中配置,如下图.也可以在上面的那个Net Configuration Assistant中配置,只是Net Manager比较方便些. Ora ...
- if判断的时候明明是null却不走null的函数体?
String phoneStr = String.valueOf(parmMap.get(phone.trim())); if(StringUtils.isBlank(phoneStr) || &qu ...
- SpringMVC -- 必知必会
SpringMVC基于模型--视图--控制器(Model-View-Controller,MVC)模式实现,属于SpringFrameWork的后续产品,已经融合在SpringWebFlow里面.它通 ...
- iOS 中集成海康威视 摄像视频
本文原文地址 http://www.cnblogs.com/qianLL/p/6652104.html 一.要导入相关的库,注意 这里比较坑的是 要用和他一样的 如果开始的工程中用了AFN或者MJE ...
- 浅析套接字中SO_REUSEPORT和SO_REUSEADDR的区别
Socket的基本背景 在讨论这两个选项的区别时,我们需要知道的是BSD实现是所有socket实现的起源.基本上其他所有的系统某种程度上都参考了BSD socket实现(或者至少是其接口),然后开始了 ...
- HTML中的那些bug
1.语法检测时提示有多余的结束标签 <!doctype html> <html> <head> <meta charset="utf-8" ...
- JS中的对象之原型
对象 ECMAScript做为一个高度抽象的面向对象语言,是通过_对象_来交互的.即使ECMAScript里边也有_基本类型_,但是,当需要的时候,它们也会被转换成对象. 一个对象就是一个属性集合,并 ...