题意不用多说,求平面最近点对的,很简单……我又是一大堆的板子往上面一放,代码就比较长
最近点对,就是分治的方法来求,一半一半地分下去,同时找到x最近的一些点,然后合并的时候枚举比刚刚求到的距离范围内的点,然后求y,整个复杂度应该湿nlogn级别的……还是该理解理解然后脱离板子。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
const int maxn = (int)1e5 + 10;
const double eps = 1e-8;
int cmp(double x){
if (fabs(x) < eps) return 0;
if (x > 0) return 1;
return -1;
}
inline double sqr(double x){
return x * x;
}
struct point{
double x, y;
point(){}
point(double a, double b) : x(a), y(b){}
void input(){
scanf("%lf%lf", &x, &y);
}
friend point operator + (const point &a, const point &b){
return point(a.x + b.x, a.y + b.y);
}
friend point operator - (const point &a, const point &b){
return point(a.x - b.x, a.y - b.y);
}
friend bool operator == (const point &a, const point &b){
return cmp(a.x - b.x) == 0 && cmp(a.y - b.y) == 0;
}
friend point operator * (const double &a, const point &b){
return point(a * b.x, a * b.y);
}
friend point operator / (const point &a, const double &b){
return point(a.x / b, a.y / b);
}
double norm(){
return sqrt(sqr(x) + sqr(y));
}
};
double det(const point &a, const point &b){
return a.x * b.y - a.y * b.x;
}
double dot(const point &a, const point &b){
return a.x * b.x + a.y * b.y;
}
double dist(const point &a, const point &b){
return (a - b).norm();
}
point rotate_point(const point &p, double A){
double tx = p.x, ty = p.y;
return point(tx * cos(A) - ty * sin(A), tx * sin(A) + ty * cos(A));
}
point a[maxn];
int n, s[maxn];
bool cmpx(int i, int j){
return cmp(a[i].x - a[j].x) < 0;
}
bool cmpy(int i, int j){
return cmp(a[i].y - a[j].y) < 0;
}
double min_dist(point a[], int s[], int l, int r){
double ans = 1e100;
if (r - l < 20){
for (int q = l; q < r; q++)
for (int w = q + 1; w < r; w++)
ans = min(ans, (a[s[q]] - a[s[w]]).norm());
return ans;
}
int tl, tr, m = (l + r) >> 1;
ans = min(min_dist(a, s, l, m), min_dist(a, s, m, r));
for (tl = l; a[s[tl]].x < a[s[m]].x - ans; tl++);
for (tr = r - l; a[s[tr]].x > a[s[m]].x + ans; tr--);
sort(s + tl, s + tr, cmpy);
for (int q = tl; q < tr; q++)
for (int w = q + 1; w < min(tr, q + 6); w++)
ans = min(ans, (a[s[q]] - a[s[w]]).norm());
sort(s + tl, s + tr, cmpx);
return ans;
}
double Min_Dist(point a[], int s[], int n){
for (int i = 0; i < n; i++)
s[i] = i;
sort(s, s + n, cmpx);
return min_dist(a, s, 0, n);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in", "rt", stdin);
#endif
while(scanf("%d", &n) == 1 && n){
for (int i = 0; i < n; i++)
a[i].input();
memset(s, 0, sizeof(s));
double ans = Min_Dist(a, s, n);
printf("%.2lf\n", ans / 2.0);
}
return 0;
}