题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1337
随机增量法O(n)了事
代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdlib>
using namespace std ;
#define rep( i , l , r ) for ( int i = l ; i <= r ; ++ i )
const int maxn = 100100 ;
typedef long double ld ;
const ld esp = 0.000000001 ;
ld sqr( ld x ) {
return x * x ;
}
struct point {
ld x , y ;
void oper( ld _x , ld _y ) {
x = _x , y = _y ;
}
ld dist( point p ) {
return sqrt( sqr( x - p.x ) + sqr( y - p.y ) ) ;
}
} P[ maxn ] , p0 ;
int n ;
ld r ;
void cal( point a , point b , point c ) {
ld a1 = 2 * ( b.x - a.x ) , b1 = 2 * ( b.y - a.y ) , c1 = sqr( b.x ) + sqr( b.y ) - sqr( a.x ) - sqr( a.y ) ;
ld a2 = 2 * ( c.x - a.x ) , b2 = 2 * ( c.y - a.y ) , c2 = sqr( c.x ) + sqr( c.y ) - sqr( a.x ) - sqr( a.y ) ;
p0.y = ( c1 * a2 - c2 * a1 ) / ( b1 * a2 - a1 * b2 ) ;
p0.x = ( c1 - b1 * p0.y ) / a1 ;
r = p0.dist( a ) ;
}
int main( ) {
scanf( "%d" , &n ) ;
rep( i , 1 , n ) {
double x , y ; scanf( "%lf%lf" , &x , &y ) ;
P[ i ].oper( ld( x ) , ld( y ) ) ;
}
random_shuffle( P + 1 , P + n + 1 ) ;
p0 = P[ 1 ] , r = 0 ;
rep( i , 2 , n ) if ( p0.dist( P[ i ] ) > r - esp ) {
p0.x = ( P[ i ].x + P[ 1 ].x ) / 2.0 , p0.y = ( P[ i ].y + P[ 1 ].y ) / 2.0 ;
r = p0.dist( P[ i ] ) ;
rep( j , 2 , i - 1 ) if ( p0.dist( P[ j ] ) > r - esp ) {
p0.x = ( P[ i ].x + P[ j ].x ) / 2.0 , p0.y = ( P[ i ].y + P[ j ].y ) / 2.0 ;
r = p0.dist( P[ j ] ) ;
rep( k , 1 , j - 1 ) if ( p0.dist( P[ k ] ) > r - esp ) cal( P[ i ] , P[ j ] , P[ k ] ) ;
}
}
printf( "%.3f\n" , double( r ) ) ;
return 0 ;
}