洛谷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) 题目描述 最近欢欢看到一本有关火星的书籍,其中她被一个加法运算所困惑,由于她的运算水平有限.她想向你求助,作为一位优秀的程序员,你当然不会拒 ...
随机推荐
- $.ajax json 在本地正常 上传服务器不正常
$.ajax( { url:"url",// 跳转到 action data:{name ...
- @GetMapping和@PostMapping 和@RequestMapping区别
@GetMapping 用于将HTTP GET请求映射到特定处理程序方法的注释. 具体来说,@GetMapping是一个作为快捷方式的组合注释@RequestMapping(method = Requ ...
- vue--组件中的自定义事件
父组件通过props向子组件传递数据,子组件通过自定义事件向父组件传递信息. 在子组件中通过$emit触发事件,父组件在直接使用子组件的地方使用v-on(即@)来监听子组件触发的事件. 举例:(不知道 ...
- oracle 执行跟踪
一.sql_trace的介绍 --打开trace文件设置,把sql trace设置为true,就会在udump目录中增加一个trc文件.alter session set sql_trace=true ...
- 优雅的创建map/list集合
带值的集合的创建 String[] a = {"1","2","3","4"}; boolean q = ArrayUt ...
- Django 外键ForeignKey中的on_delete
当你在Django中删除了一个有着外键关联的数据时,比如一个作者和他名下的所有的书的信息,书的外键是作者(一个作者可有好多本书),当你把作者的信息从数据库中删除时,Django提供了一下几个参数来对作 ...
- 使用WinPcap编程
创建一个使用 wpcap.dll 的应用程序 用 Microsoft Visual C++ 创建一个使用 wpcap.dll 的应用程序,需要按一下步骤: 在每一个使用了库的源程序中,将 pcap.h ...
- Java IO(四--字符流基本使用
在上一节,介绍了字节流的基本使用,本节介绍一下字符流的使用 Reader: public abstract class Reader implements Readable, Closeable { ...
- docker数据卷的管理和使用
数据卷的使用,数据库可以保证如果容器出现问题但是数据不丢失的作用,比如MySQL/date下的数据 或者Nginx根目录下的index.html 查看数据卷 [root@docker ~]# dock ...
- C++中const与constexpr区别
对于对象来说 const指的是编译期常量和运行时常量,两者并没有区分 constexpr特指编译期常量 对于函数来说 const可以修饰类的成员函数,被修饰的函数在执行期间不会改变对象的值. clas ...