分治法之最近点对问题

https://blog.csdn.net/sinat_35678407/article/details/82874216

/*分治法求最近点对问题*/
/*
思路:
1.将坐标按x升序排列,并取中值分为两半
2.递归寻找PL和PR中的最近点对,设其找到的最近点对的距离分别是δL和 δR ,δ=min(δL, δR)
3.中间为x,则(x-δ,x+δ)为带状区域,在这里找最小的距离进行比较,带状区域的点按y值升序排列,则对于每个点 P。只需检查他后面的6个点就行 
*/
#include <iostream>
#include <algorithm>
#include <cmath>
#define INF 0x6FFFFFFF
using namespace std;

struct Node{
	double x, y;

	friend bool operator < (const Node &a, const Node &b){
		if(a.x == b.x)
			return a.y < b.y;
		return a.x < b.x;
	}
};

Node* Point = NULL;
/**
 * Calculate the distance between two points.
 * @return   [double, the distance between a and b]
 */
double _distance(const Node a, const Node b)
{
	return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}

double smaller(double p, double q)
{
	return (p > q) ? q : p;
}

double Closest_distance(int left, int right)
{
	double d = INF;
	double distance_tmp;

	if(left == right)
		return 0;
	if(right == left+1)
		return _distance( Point[left], Point[right] );
	int mid = (left + right) / 2;

	d = smaller( Closest_distance(left,mid) , Closest_distance(mid,right) );

	for(int i=mid-1; i>=left && Point[mid].x - Point[i].x < d; i--){
		for(int j = mid+1; j<=right && Point[j].x - Point[mid].x < d && fabs( Point[i].y - Point[j].y) < d; j++){
			distance_tmp = _distance( Point[i], Point[j] );
			if(distance_tmp < d)
				d = distance_tmp;
		}
	}

	return d;
}

int main()
{
    int n;
    cin>>n;
    Point = new Node[n];
    for(int i=0; i<n ; i++){
    	cin>>Point[i].x>>Point[i].y;
    }
    sort(Point,Point+n);
    cout<<Closest_distance(0,n-1)<<endl;
    return 0;
}
发布了63 篇原创文章 · 获赞 3 · 访问量 1709

猜你喜欢

转载自blog.csdn.net/qq_34405401/article/details/103191824
今日推荐