最近点对问题

给定平面上n个点,求距离最近的两个点的距离。

1<=n<=10000

算法分析:

二分区域,主要检查那些处于x0-d<x<x0+d且yp-d<y<=yp的点。

代码:

#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<utility>
using namespace std;
typedef pair<double,double>P;
#define maxn 5005
#define INF 1e8
#define eps 0.00001
P p[maxn];

bool comp_y(P a,P b){
	return a.second-b.second<eps;
}
double closest(P *p,int n){
	if(n<=1)return INF;
	int m=n/2;
	double x=p[m].first;
	double d=min(closest(p,m),closest(p+m,n-m));//二分
	inplace_merge(p,p+m,p+n,comp_y);
	vector<P>b;
	//for核心语句
	for(int i=0;i<n;i++){
		if(fabs(p[i].first-x)>=d)continue;
		for(int j=0;j<b.size();j++){
			double dx=p[i].first-b[b.size()-j-1].first;
			double dy=p[i].second-b[b.size()-j-1].second;
			if(dy>=d)break;
			d=min(d,sqrt(dx*dx+dy*dy));
		}
		b.push_back(p[i]);
	}
	return d;
}
int main(){
	int n;
	scanf("%d",&n);
	int i=0;
	while(i<n){
		scanf("%lf%lf",&p[i].first,&p[i].second);
		i++;
	}
	sort(p,p+n);
	printf("%.2lf\n",closest(p,n));
}
时间: 2024-12-29 11:16:52

最近点对问题的相关文章

最近点对问题的解法

回到二维的情况.参考一维退化版本的解法,首先进行分解和求解步骤. 分解:将所有点按照横坐标从中心分成两部分. 求解:递归求解两半部分的最近点对,左右两半部分依次为 p_1,p_2p?1??,p?2?? 和 q_1,q_2q?1??,q?2??. 合并:令 d = min\{|p_1-p_2|, |q_1-q_2|\}d=min{∣p?1??−p?2??∣,∣q?1??−q?2??∣}.如下左图所示,除了两半部分各自的最近点对之外,只需要计算横跨图中左右两半部分区域的点对的距离最小值,再和 dd 

hdu1007 平面最近点对(暴力+双线程优化)

突发奇想,用双线程似乎可以优化一些暴力 比如说平面最近点对这个题目,把点复制成2份 一份按照x排序,一份按照y排序 然后双线程暴力处理,一份处理x,一份处理y 如果数据利用x递减来卡,那么由于双线程,它卡不住y 如果数据利用y递减来卡,那么卡不住x 这样暴力n^2就可以过了 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algori

平面最近点对(分治nlogn)

平面最近点对,是指给出平面上的n个点,寻找点对间的最小距离 首先可以对按照x为第一关键字排序,然后每次按照x进行分治,左边求出一个最短距离d1,右边也求出一个最短距离d2,那么取d=min(d1, d2) 然后只需考虑横跨左右两侧的点,不妨枚举左侧的点pi 那么很显然的是如果pi距离中间的点超过了d,便可以直接舍去,只需考虑距离中间点小于d的点 这样一来就可以对每个pi画一个边长为2d的正方形,易证,矩形内最多存在8个点. 那么关键问题就是要快速找这8个点 朴素做法是对分治后的点进行快排,这样复

bzoj2458: [BeiJing2011]最小三角形 最近点对

类似分治最近点对的方法乱搞一下就行. #include<bits/stdc++.h> #define N 200010 #define M (s+t>>1) using namespace std; struct vec{ int x,y; }u[N],v[N]; bool foo(vec a,vec b){ return a.x<b.x; } bool bar(vec a,vec b){ return a.y<b.y; } double sqr(double x){

POJ 3714 Raid(平面最近点对)

解题思路: 分治法求平面最近点对,点分成两部分,加个标记就好了. #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <vector> #include <queue> #include <algorithm> #include <iomanip>

【HDOJ】P1007 Quoit Design (最近点对)

题目意思很简单,意思就是求一个图上最近点对. 具体思想就是二分法,这里就不做介绍,相信大家都会明白的,在这里我说明一下如何进行拼合. 具体证明一下为什么只需要检查6个点 首先,假设当前左侧和右侧的最小值为d,那么对于一个点,如果有个最小值小于d,那么一定存在于上d下d左d右d的一块区域内,又因为是从左到右,从上到下,所以左侧的那部分匹配的区域会重叠,也就是对于左侧的区域,完全没有必要去进行匹配.所以只需要对右侧d,上下d的区域进行匹配,而假设这个区域内的所以点的距离为d那么最多为6个,那么如果长

新浪微博客户端(53)-记录用户最近点击表情

设计思路:每当用户点击一个表情,就将该表情(DJEmotion)存储到沙盒,当用户切换到"最近"栏目时,从沙盒中取出用户最近点击的表情列表,进行显示. 1. 保存DJEmotion DJEmotion.h #import <Foundation/Foundation.h> // 因为要保存最近使用的表情到沙盒,所以该对象须实现NSCoding协议 @interface DJEmotion : NSObject <NSCoding> /** Emotion 中文字

ICP算法(Iterative Closest Point迭代最近点算法)

标签: 图像匹配ICP算法机器视觉 2015-12-01 21:09 2217人阅读 评论(0) 收藏 举报 分类: Computer Vision(27) 版权声明:本文为博主原创文章,未经博主允许不得转载. 最近在做点云匹配,需要用c++实现ICP算法,下面是简单理解,期待高手指正. ICP算法能够使不同的坐标下的点云数据合并到同一个坐标系统中,首先是找到一个可用的变换,配准操作实际是要找到从坐标系1到坐标系2的一个刚性变换. ICP算法本质上是基于最小二乘法的最优配准方法.该算法重复进行选

Codeforces 429D Tricky Function 最近点对

题目链接:点击打开链接 暴力出奇迹. 正解应该是最近点对,以i点为x轴,sum[i](前缀和)为y轴,求任意两点间的距离. 先来个科学的暴力代码: #include<stdio.h> #include<string.h> #include<vector> #include<algorithm> #include<iostream> #include<queue> using namespace std; #define N 10005

最近点对(Java实现)

最近点对问题: 在二维平面上的n个点中,快速的最近的一对点的距离. java实现: package p2; import static java.lang.Math.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Scanner; public class CloestPair {