1. 程式人生 > >HDU - 1007 平面最近點對

HDU - 1007 平面最近點對

可能 eat use pla 合並 ase coord int largest

Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched at some toys, with all the toys encircled awarded.
In the field of Cyberground, the position of each toy is fixed, and the ring is carefully designed so it can only encircle one toy at a time. On the other hand, to make the game look more attractive, the ring is designed to have the largest radius. Given a configuration of the field, you are supposed to find the radius of such a ring.

Assume that all the toys are points on a plane. A point is encircled by the ring if the distance between the point and the center of the ring is strictly less than the radius of the ring. If two toys are placed at the same point, the radius of the ring is considered to be 0.

InputThe input consists of several test cases. For each case, the first line contains an integer N (2 <= N <= 100,000), the total number of toys in the field. Then N lines follow, each contains a pair of (x, y) which are the coordinates of a toy. The input is terminated by N = 0.
OutputFor each test case, print in one line the radius of the ring required by the Cyberground manager, accurate up to 2 decimal places.
Sample Input

2
0 0
1 1
2
1 1
1 1
3
-1.5 0
0 0
0 1.5
0

Sample Output

0.71
0.00
0.75

思路:每次按x坐標分成左右兩坨,處理完左右兩坨後考慮中間相鄰的那部分,考慮可能更新答案的點集,按y值雙指針移動即可,一個trick是合並兩個子問題時同時類似歸並排序將點按y值順便排好序而不是每次快排重新排序。
每次合並代價O(n),這樣最終復雜度nlogn。
技術分享圖片
  1 #include <iostream>
  2 #include <fstream>
  3 #include <sstream>
  4 #include <cstdlib>
  5
#include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16
#include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 struct point { 45 double x, y; 46 void input() { 47 scanf("%lf%lf", &x, &y); 48 } 49 double dis(const point &p) { 50 return sqrt((x - p.x) * (x - p.x) + (y - p.y) * (y - p.y)); 51 } 52 bool operator < (const point &p) const { 53 return x < p.x;} 54 } p[100015], q[100015], p1[100015], p2[100015]; 55 int n; 56 double dis; 57 void mymerge(int s, int e) { 58 if (s == e) return; 59 int mi = s + e >> 1; 60 mymerge(s, mi); 61 mymerge(mi + 1, e); 62 double d2 = p[mi].x + dis; 63 double d1 = p[mi + 1].x - dis; 64 int i = s, j = mi + 1, k = s, i1 = 1, i2 = 1; 65 while (i <= mi && j <= e) { 66 if (p[i].y < p[j].y) { 67 if (d1 - EPS <= p[i].x && p[i].x <= d2 + EPS) { 68 p1[i1++] = p[i]; 69 } 70 q[k++] = p[i++]; 71 } 72 else { 73 if (d1 - EPS <= p[j].x && p[j].x <= d2 + EPS) { 74 p2[i2++] = p[j]; 75 } 76 q[k++] = p[j++]; 77 } 78 } 79 while (i <= mi) { 80 if (d1 - EPS <= p[i].x && p[i].x <= d2 + EPS) { 81 p1[i1++] = p[i]; 82 } 83 q[k++] = p[i++]; 84 } 85 while (j <= e) { 86 if (d1 - EPS <= p[j].x && p[j].x <= d2 + EPS) { 87 p2[i2++] = p[j]; 88 } 89 q[k++] = p[j++]; 90 } 91 for (int i = s; i <= e; ++i) p[i] = q[i]; 92 for (int i = 1, j = 1; i < i1 && j < i2; ++i) { 93 while (j < i2 && p2[j].y < p1[i].y - dis) ++j; 94 for (int k = j; k < i2 && p2[j].y < p1[i].y + dis; ++k) { 95 double td = p1[i].dis(p2[j]); 96 dis = min(dis, td); 97 } 98 } 99 } 100 int main() { 101 while (~scanf("%d", &n) && n) { 102 for (int i = 1; i <= n; ++i) { 103 p[i].input(); 104 } 105 sort(p + 1, p + n + 1); 106 dis = 1e18; 107 mymerge(1, n); 108 printf("%.2f\n", dis / 2); 109 } 110 return 0; 111 }
View Code

HDU - 1007 平面最近點對