1. 程式人生 > >POJ平面最近點對

POJ平面最近點對

描述

二維平面上有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; }