寻找最近点对
算法导论上一个经典算法,讲解可看 http://yzmduncan.iteye.com/blog/1432880
AC代码的复杂度为 n*lgn*lgn,算法导论上讲还可以通过“预排序”,不用每次都按照y排序,复杂度可下降为n*lgn。
http://acm.hdu.edu.cn/status.php 上可以AC。
#include<stdio.h> #include<math.h> #include<algorithm> using namespace std; #define MAX 100005 #define Inf 2e20 struct Point { double x; double y; }; Point a[MAX]; Point tmp[MAX]; int cmpX(Point a, Point b) { return a.x < b.x; } int cmpY(Point a, Point b) { return a.y < b.y; } double dis(Point* a, int i, int j) { return sqrt( (a[i].x - a[j].x) * (a[i].x - a[j].x) + (a[i].y - a[j].y) * (a[i].y - a[j].y)); } double minDis(int left, int right) { double d = Inf; if (left == right) return d; if (left + 1 == right) { return dis(a, left, right); } if (left + 2 == right) { return min(min(dis(a, left, left + 1), dis(a, left, right)), dis(a, left + 1, right)); } int mid = left + (right - left) / 2; double minLeft = minDis(left, mid); double minRight = minDis(mid + 1, right); d = min(minLeft, minRight); int k = 0; for (int i = left; i <= right; i++) { if (fabs(a[mid].x - a[i].x) <= d) { tmp[k].x = a[i].x; tmp[k].y = a[i].y; k++; } } sort(tmp, tmp + k, cmpY); for (int i = 0; i < k; i++) { //j<i+8优化,否则会超时 for (int j = i + 1; j < k && j < i + 8; j++) { if (dis(tmp, i, j) < d) { d = dis(tmp, i, j); } } } return d; } int main() { freopen("my.in", "r", stdin); int n; while (scanf("%d", &n) != EOF) { if (n == 0) break; for (int i = 0; i < n; i++) { scanf("%lf%lf", &a[i].x, &a[i].y); } sort(a, a + n, cmpX); double res = minDis(0, n - 1); printf("%.2lf\n", res / 2); } return 0; }