这题做了很久,一直都是1秒多,真不知道他们300ms是怎么做出来的。看了网上的代码,大部分都是O(nlgnlgn),于是绞尽脑汁,写了个O(nlgn)的代码,但是时间上没有显著地提高。
/**
* O(nlogn)
* zoj_2107
**/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
int const MAXN = 100010;
double const eps = 1e-20;
struct Point {
double x, y;
};
int n;
Point toy[MAXN];
int yarr[MAXN];
int buffer[2*MAXN];
inline bool Dxlessy( double x, double y ) {
return x+eps < y;
}
inline bool Dxequaly( double x, double y ) {
return fabs(x-y)<eps;
}
inline double Dmin( double x, double y ) {
if ( Dxlessy( x, y ) )
return x;
return y;
}
bool pcmp( Point const& pa, Point const& pb ) {
if ( Dxlessy( pa.x, pb.x ) )
return true;
if ( Dxequaly( pa.x, pb.x ) && Dxlessy( pa.y, pb.y ) )
return true;
return false;
}
bool ycmp( int a, int b ) {
if ( Dxlessy( toy[a].y, toy[b].y ) )
return true;
if ( Dxequaly( toy[a].y, toy[b].y ) && Dxlessy( toy[a].x, toy[b].x ) )
return true;
return false;
}
inline double PointDist( Point const& a, Point const& b ) {
return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) );
}
double NearestP( int start, int end, int begin ) {
int cnt = end-start+1;
double dist;
if ( 2 == cnt ) {
return PointDist( toy[start], toy[end] );
}
if ( 3 == cnt ) {
dist = Dmin( PointDist( toy[start], toy[start+1] ), PointDist( toy[start+1], toy[end] ) );
dist = Dmin( dist, PointDist( toy[start], toy[end] ) );
return dist;
}
int le, i, j, a, b, k;
double x0, d1, d2;
le = start+(cnt>>1)-1;
x0 = toy[le].x;
a = start;
b = le+1;
for ( i = begin; i < begin+cnt; ++ i ) {
if ( buffer[i] <= le ) //left part
yarr[a++] = buffer[i];
else
yarr[b++] = buffer[i];
}
memcpy( buffer+begin+cnt, yarr+start, (cnt>>1)*sizeof(int) );
d1 = NearestP( start, le, begin+cnt ); //yarr[ start, le ]
if ( d1 < eps )
return 0.0;
memcpy( buffer+begin+cnt, yarr+le+1, (cnt-(cnt>>1))*sizeof(int) );
d2 = NearestP( le+1, end, begin+cnt ); //yarr[ le+1, end ]
if ( d2 < eps )
return 0.0;
dist = Dmin( d1, d2 );
a = start;
for ( i = begin; i < begin+cnt; ++ i ) {
if ( !Dxlessy( toy[ buffer[i] ].x, x0-dist )
&& !Dxlessy( x0+dist, toy[ buffer[i] ].x ) )
yarr[a++] = buffer[i];
}
for ( i = start; i < a-1; ++ i ) {
b = i+8>a ? a : i+8;
for ( j = i+1; j < b; ++ j ) {
dist = Dmin( dist, PointDist( toy[ yarr[i] ], toy[ yarr[j] ] ) );
}
}
return dist;
}
int main()
{
int i;
double result;
while ( scanf("%d", &n) != EOF ) {
if ( 0 == n )
break;
for ( i = 0; i < n; ++ i ) {
scanf("%lf%lf", &toy[i].x, &toy[i].y );
buffer[i] = i;
}
sort( toy, toy+n, pcmp );
sort( buffer, buffer+n, ycmp );
result = NearestP( 0, n-1, 0 );
printf("%.2lf\n", result/2.0);
}
return 0;
}