这题采用分割法,利用hash和二分的思想可以写出高效算法。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int size_n = 10000 + 100;
double a[size_n][2];
int cur;
const int h_size = 100001;
int h[size_n * 10];
int s[size_n][2];
unsigned long long s2[size_n];
double ebsp = 1e-4;
int f(double x , int n)
{
cur = 1;
memset(h , 0 , sizeof(h));
double t = sqrt(0.5) * x;
int len = (int)(40001.1 / t) + 1;
for(int i = 0 ; i < n ; ++i)
{
int tx = (int)(a[i][0] / t);
int ty = (int)(a[i][1] / t);
unsigned long long total = (unsigned long long)tx * len + ty;
int index = (total) % h_size;
s2[cur] = total;
s[cur][1] = h[index];
s[cur][0] = i;
h[index] = cur;
unsigned long long des = s2[cur];
for(int k = s[cur++][1] ; k ; k = s[k][1])
{
if((s2[k] == des)) return 1;
}
}
return 0;
}
int d[][2] = {{-3 , -3} , {-3 , -2} , {-3 , -1} , {-3 , 0} , {-3 , 1} , {-3 , 2} , {-3 , 3} ,
{-2 , -3} , {-2 , -2} , {-2 , -1} , {-2 , 0} , {-2 , 1} , {-2 , 2} , {-2 , 3} ,
{-1 , -3} , {-1 , -2} , {-1 , -1} , {-1 , 0} , {-1 , 1} , {-1 , 2} , {-1 , 3} ,
{0 , -3} , {0 , -2} , {0 , -1} , {0 , 1} , {0 , 2} , {0 , 3} ,
{1 , -3} , {1 , -2} , {1 , -1} , {1 , 0} , {1 , 1} , {1 , 2} , {1 , 3} ,
{2 , -3} , {2 , -2} , {2 , -1} , {2 , 0} , {2 , 1} , {2 , 2} , {2 , 3} ,
{3 , -3} , {3 , -2} , {3 , -1} , {3 , 0} , {3 , 1} , {3 , 2} , {3 , 3}};
double g(double dis , int n)
{
double t = sqrt(0.5) * dis;
int len = (int)(40001.1 / t) + 1;
double min_r = 10000;
for(int i = 0 ; i < n ; ++i)
{
int x = (int)(a[i][0] / t);
int y = (int)(a[i][1] / t);
for(int j = 0 ; j < 48 ; ++j)
{
int tx = x + d[j][0];
if(tx < 0 || tx >= len) continue;
int ty = y + d[j][1];
if(ty < 0 || tx >= len) continue;
unsigned long long total = (unsigned long long)tx * len + ty;
int index = total % h_size;
int r = h[index];
for( ; r ; r = s[r][1])
{
int tt = s[r][0];
if(tt == i) continue;
double tr = sqrt((a[i][0] - a[tt][0] ) * (a[i][0] - a[tt][0]) + (a[i][1] - a[tt][1]) * (a[i][1] - a[tt][1]));
if(min_r > tr) min_r = tr;
}
}
}
return min_r;
}
int main()
{
int n;
while(scanf("%d" , &n) == 1 && n)
{
for(int i = 0 ; i < n ; ++i)
scanf("%lf%lf" , a[i] , a[i] + 1);
int r;
double now = 20000;
do{
now /= 2;
r = f(now , n);
if(now < 1e-4) break;
}while(r);
double res;
if(now < 1e-4) res = 0;
else res = g(now , n);
if(res < 10000) printf("%.4f\n" , res);
else printf("INFINITY\n");
}
return 0;
}