描述
二维平面上有N个点,求最近点对之间的距离。
输入第一行一个整数T,表示有T组测试数据
每组测试数据第一行一个整数N(2<=N<=1e5)表示平面有N个点
接下来有N行,每行两个整数X Y(-1e9<=X,Y <=1e9)表示点的坐标输出输出最近点对的距离,精确到小数点后6位样例输入
1 3 1 0 1 1 0 1
样例输出
1.000000
#include <iostream> #include <math.h> #include <string.h> #include <algorithm> #include <vector> #include <queue> #include <iostream> #include <math.h> #include <string.h> #include <algorithm> #include <vector> #include <queue> #define INF 0x3f3f3f3f using namespace std; struct point{ double x, y; point(double x, double y) :x(x), y(y){}; }; vector<point> vr; bool cmpx(point a, point b){ return a.x < b.x; } bool cmpy(int a, int b){ return vr[a].y < vr[b].y; } double getdis(point a,point b){ return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2)); } double mind(double a, double b){ return a < b ? a : b; } double fun(int left, int right){ if (left + 1 == right) return getdis(vr[left], vr[right]); if (left + 2 == right)return mind(getdis(vr[left], vr[left + 1]), mind(getdis(vr[left], vr[right]), getdis(vr[left + 1], vr[right]))); int mid = (left + right) >> 1; double d = mind(fun(left, mid), fun(mid + 1, right)); vector<int>tv; for (int i = left; i <= right; i++){ if (abs(vr[i].x - vr[mid].x) < d) tv.push_back(i); } sort(tv.begin(), tv.end(), cmpy); for (int i = 0; i < tv.size()-1; i++) for(int j=i+1;j<tv.size();j++){ if (abs(vr[tv[i]].y - vr[tv[j]].y) < d) d = mind(d, getdis(vr[tv[i]], vr[tv[j]])); } return d; } int main() { int T,N; double a, b; scanf("%d", &T); while (T--){ vr.clear(); scanf("%d", &N); for (int i = 0; i < N; i++){ scanf("%lf %lf", &a, &b); vr.push_back(point(a, b)); } sort(vr.begin(), vr.end(), cmpx); printf("%.6lf\n",fun(0, N - 1)); } return 0; }