【hdu1007】最近点对
http://acm.hdu.edu.cn/showproblem.php?pid=1007
分治法的经典应用,复杂度可以证明为nlognlogn
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <map> 7 #include <stack> 8 #include <string> 9 #include <ctime> 10 #include <queue> 11 #define mem0(a) memset(a, 0, sizeof(a)) 12 #define mem(a, b) memset(a, b, sizeof(a)) 13 #define lson l, m, rt << 1 14 #define rson m + 1, r, rt << 1 | 1 15 #define eps 0.0000001 16 #define lowbit(x) ((x) & -(x)) 17 #define memc(a, b) memcpy(a, b, sizeof(b)) 18 #define x_x(a) ((a) * (a)) 19 using namespace std; 20 #define LL __int64 21 #define DB double 22 #define pi 3.14159265359 23 #define MD 10000007 24 #define INF (int)1e9 25 struct Point { 26 double x, y; 27 Point(double x = 0, double y = 0):x(x), y(y) {} 28 void inp() { 29 scanf("%lf%lf", &x, &y); 30 } 31 bool operator < (const Point &a) const { 32 return x < a.x || x == a.x && y < a.y; 33 } 34 } pn[120000], tmp[120000]; 35 int cmpy(Point i, Point j) 36 { 37 return i.y < j.y; 38 } 39 double dist(Point a, Point b) 40 { 41 return sqrt(x_x(a.x - b.x) + x_x(a.y - b.y)); 42 } 43 double solve(int l, int r) 44 { 45 if(l == r) return INF; 46 int m = (l + r) >> 1; 47 double d1 = solve(l, m), d2 = solve(m + 1, r), d = min(d1, d2); 48 int nn = 0; 49 for(int i = l; i <= r; i++) { 50 if(dist(pn[i], pn[m]) <= d) { 51 tmp[++nn] = pn[i]; 52 } 53 } 54 sort(tmp + 1, tmp + nn, cmpy); 55 for(int i = 1; i < nn; i++) { 56 double mind = INF; 57 for(int j = i + 1; j <= nn && tmp[j].y - tmp[i].y <= d; j++) { 58 mind = min(mind, dist(tmp[i], tmp[j])); 59 } 60 d = min(d, mind); 61 } 62 return d; 63 } 64 int main() 65 { 66 //freopen("input.txt", "r", stdin); 67 //freopen("output.txt", "w", stdout); 68 int n; 69 while(cin>> n, n) { 70 for(int i = 1; i <= n; i++) pn[i].inp(); 71 sort(pn + 1, pn + 1 + n); 72 double t = solve(1, n); 73 printf("%.2f\n", t / 2); 74 } 75 return 0; 76 }