这个看了网上的题解,应该不是O(n*log(n))的复杂度,那个两重循环是有优化的可能的,应该只用检查附近的6个点就行了。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
using namespace std;
struct P
{
double x, y;
P() {}
P(double x, double y) : x(x), y(y) {}
P operator =(P p)
{
x = p.x, y = p.y;
return *this;
}
};
P ans_arr[100117], in_arr[100117];
bool cmpx(P a, P b)
{
return a.x < b.x;
}
bool cmpy(P a, P b)
{
return a.y < b.y;
}
double get_dist(P a, P b)
{
return ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
double nearest_pair(int l, int r)
{
if(r == l + 1) return get_dist(in_arr[l], in_arr[r]);
else if(r == l + 2) return min(get_dist(in_arr[l], in_arr[l + 1]), min(get_dist(in_arr[l], in_arr[r]), get_dist(in_arr[l + 1], in_arr[r])));
else
{
int mid = (l + r) >> 1, cnt = 0;
double ans = min(nearest_pair(l, mid), nearest_pair(mid + 1, r));
for(int i = l; i <= r; ++i)
{
if(in_arr[mid].x - ans <= in_arr[i].x && in_arr[i].x <= in_arr[mid].x)
{
ans_arr[cnt++] = in_arr[i];
}
}
sort(ans_arr, ans_arr + cnt, cmpy);
for(int i = 0; i < cnt; ++i)
{
for(int j = i + 1; j < cnt; ++j)
{
double tmp = get_dist(ans_arr[i], ans_arr[j]);
if(tmp > ans) break;
ans = tmp;
}
}
return ans;
}
}
int main()
{
// freopen("in.in", "r", stdin);
int n;
while(scanf("%d", &n) != EOF && n != 0)
{
memset(in_arr, 0, sizeof(in_arr));
memset(ans_arr, 0, sizeof(ans_arr));
for(int i = 0; i < n; ++i)
{
scanf("%lf %lf", &in_arr[i].x, &in_arr[i].y);
}
sort(in_arr, in_arr + n, cmpx);
printf("%.2lf\n", sqrt(nearest_pair(0, n - 1)) / 2.0);
}
return 0;
}