最近点对问题
最近点对问题是利用分治法解决的经典问题之一。
问题描述
设在一个点集S中存在n个点,找出距离最相近的一对点p1和p2,最近点对可能不止一对,输出一对即可。
分析设计
在n个点中找出距离最近的一对点,我们首先可以想到的方法就是暴力穷举的方法:遍历整个点集,计算每一对点之间的距离d,就能找出最短距离dmin。
显然这样的方法时间复杂度为O(n2),时间复杂度太高,若问题规模较大,穷举的算法并不是一个合适的算法。
在利用分治法解决该问题时,我们先要考虑划分,即将整个点集划分为两各部分S1和S2,每个子点集的点的数量都为n/2,最近点对会出现以下三种情况:
- 点对在S1中;
- 点对在S2中;
- 点对分别在S1和S2中。
利用递归分别计算前两种情况,最后分析第三种情况。然后合并,分析比较出三者中的最小值。
利用分治法解决该问题的时间复杂度为O(nlogn)。
源代码
#include <iostream>
#include <cmath>
#include <algorithm>
#include <fstream>
#define MAX 100000
using namespace std;
//点结构
struct point {
double x, y;
}p[MAX];
int a[MAX]; //保存排序索引
//距离
double distance(point a, point b) {
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b