题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1007
题意:给出n个点求最短的两点间距离除以2。
题解:简单的分治。
其实分治就和二分很像二分的写dfs然后复杂度就是log(n*log(n)*log(n))
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> using namespace std; const int M = 1e5 + 10; const double inf = 1e20; struct TnT { double x , y; }T[M] , pp[M]; double get_dis(TnT x , TnT y) { return sqrt((x.x - y.x) * (x.x - y.x) + (x.y - y.y) * (x.y - y.y)); } bool cmpy(TnT x , TnT y) { return x.y < y.y; } bool cmpx(TnT x , TnT y) { return x.x < y.x; } double dfs(int l , int r) { double d = inf; if(l == r) { return d; } if(l + 1 == r) { return get_dis(T[l] , T[r]); } int mid = (l + r) >> 1; double d1 = dfs(l , mid); double d2 = dfs(mid + 1 , r); d = min(d1 , d2); int cnt = 0; for(int i = l ; i <= r ; i++) { if(abs(T[i].x - T[mid].x) <= d) { pp[cnt++] = T[i]; } } sort(pp , pp + cnt , cmpy); for(int i = 0 ; i < cnt ; i++) { for(int j = i + 1 ; j < cnt ; j++) { if(pp[j].y - pp[i].y > d) break; double d3 = get_dis(pp[i] , pp[j]); d = min(d , d3); } } return d; } int main() { int n; while(scanf("%d" , &n) , n) { for(int i = 1 ; i <= n ; i++) { scanf("%lf%lf" , &T[i].x , &T[i].y); } sort(T + 1 , T + 1 + n , cmpx); printf("%.2lf " , dfs(1 , n) / 2); } return 0; }