ztx

[ZOJ1450]最小圆覆盖

Posted on 2015年1月13日 11:25
/****************************************\
* Author : ztx
* Title  : [ZOJ1450]最小圆覆盖
* ALG    : 计算几何
* CMT    : 最小圆覆盖模板题
* Time   :
\****************************************/
/****************************************\
* Author : ztx
* Title  : [ZOJ1450]最小圆覆盖
* ALG    : 计算几何
* CMT    : 最小圆覆盖模板题
* Time   :
\****************************************/

#include <cstdio>
#include <algorithm>
#include <cmath>

#define  maxn  110LL

struct point {
	double x , y ;
} points[maxn] , c ;

int n ;

inline double Distance(const point& a , const point& b) {
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)) ;
}

point Circumcenter(point& a , point& b , point& c) {
	point ret ;
	double a1 = b.x-a.x , b1 = b.y-a.y , c1 = (a1*a1+b1*b1)/2 ;
	double a2 = c.x-a.x , b2 = c.y-a.y , c2 = (a2*a2+b2*b2)/2 ;
	double d = a1*b2-a2*b1 ;
	ret.x = a.x+(c1*b2-c2*b1)/d ;
	ret.y = a.y+(a1*c2-a2*c1)/d ;
	return ret ;
}

int i , j , k ;
double r ;
void Solve() {
	std::random_shuffle(points , points+n) ;
	c = points[0] ; r = 0 ;/* 注意c和r的初始化 */
	for (i = 1 ; i < n ; i ++ ) {
		if (Distance(points[i] , c) <= r) continue ;
		c = points[i] ; r = 0 ;
		for (j = 0 ; j < i ; j ++ ) {
			if (Distance(points[j] , c) <= r) continue ;
			c.x = (points[i].x+points[j].x)/2 ;
            c.y = (points[i].y+points[j].y)/2 ;
            r = Distance(points[j] , c) ;
            for (k = 0 ; k < j ; k ++ ) {
                if (Distance(points[k] , c) <= r) continue ;
                c = Circumcenter(points[i] , points[j] , points[k]) ;
                r = Distance(points[i] , c) ;
            }
		}
	}
	printf("%.8lf %.8lf %.8lf\n", c.x , c.y , r) ;
}

int main() {
	#define READ
	#ifdef  READ
		freopen("minimalcircle.in" ,"r",stdin ) ;
		freopen("minimalcircle.out","w",stdout) ;
	#endif
	int i ;
	while (scanf("%d",&n) , n) {
		for (i = 0 ; i < n ; i ++ )
			scanf("%lf%lf", &points[i].x , &points[i].y) ;
		Solve() ;
    }
	#ifdef  READ
		fclose(stdin) ; fclose(stdout) ;
	#else
		getchar() ; getchar() ;
	#endif
	return 0 ;
}