poj 2069 最小球覆盖

Description

During a voyage of the starship Hakodate-maru (see Problem 1406), researchers found strange synchronized movements of stars. Having heard these observations, Dr. Extreme proposed a theory of “super stars”. Do not take this term as a description of actors or singers. It is a revolutionary theory in astronomy.
According to this theory, starts we are observing are not independent objects, but only small portions of larger objects called super stars. A super star is filled with invisible (or transparent) material, and only a number of points inside or on its surface shine. These points are observed as stars by us.

In order to verify this theory, Dr. Extreme wants to build motion equations of super stars and to compare the solutions of these equations with observed movements of stars. As the first step, he assumes that a super star is sphere-shaped, and has the smallest possible radius such that the sphere contains all given stars in or on it. This assumption makes it possible to estimate the volume of a super star, and thus its mass (the density of the invisible material is known).

You are asked to help Dr. Extreme by writing a program which, given the locations of a number of stars, finds the smallest sphere containing all of them in or on it. In this computation, you should ignore the sizes of stars. In other words, a star should be regarded as a point. You may assume the universe is a Euclidean space.
Input

The input consists of multiple data sets. Each data set is given in the following format.

n
x1 y1 z1
x2 y2 z2
. . .
xn yn zn

The first line of a data set contains an integer n, which is the number of points. It satisfies the condition 4 <= n <= 30.

The location of n points are given by three-dimensional orthogonal coordinates: (xi, yi, zi) (i = 1, …, n). Three coordinates of a point appear in a line, separated by a space character. Each value is given by a decimal fraction, and is between 0.0 and 100.0 (both ends inclusive). Points are at least 0.01 distant from each other.

The end of the input is indicated by a line containing a zero.
Output

For each data set, the radius of the smallest sphere containing all given points should be printed, each in a separate line. The printed values should have 5 digits after the decimal point. They may not have an error greater than 0.00001.
Sample Input

4
10.00000 10.00000 10.00000
20.00000 10.00000 10.00000
20.00000 20.00000 10.00000
10.00000 20.00000 10.00000
4
10.00000 10.00000 10.00000
10.00000 50.00000 50.00000
50.00000 10.00000 50.00000
50.00000 50.00000 10.00000
0
Sample Output

7.07107
34.64102


裸的最小球覆盖。

1.对于一个点,球心就是这个点且半径无穷小。

2.对于两个点,球心是两个点线段的中点,半径就是线段长度的一半。

3.对于三个点,三个点构成的平面必为球的大圆,所以球心是三角形的外心,半径就是球心到某个点的距离。

4.对于四个点,若四个点共面则转化到3,只需考虑某三个点的情况,若四点不共面,四面体可以唯一确定一个外接球。

5.对于五个及以上点,其最小球必为其中某4个点的外接球(假设不全共面)。

我们从第五点可以知道,对于球心距离最远最多4个等距离的其他点。

所以我们随机选取一个点之后,逐渐靠近球心,让球心达道稳定态即可。


AC代码:

//#pragma GCC optimize(2)
#include<cstdio>
#include<cmath>
#include<algorithm>
//#define int long long
using namespace std;
const int N=35;
const double eps=1e-7;
struct node{double x,y,z;}t[N];
int n;
inline double dis(node a,node b){
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z));
}
double solve(){
	double step=100,res=1e20,len;
	node a; a.x=a.y=a.z=0; int id=0;
	while(step>eps){
		for(int i=1;i<=n;i++)	if(dis(a,t[i])>dis(a,t[id]))	id=i;
		len=dis(a,t[id]);
		res=min(res,len);
		a.x+=(t[id].x-a.x)/len*step;
		a.y+=(t[id].y-a.y)/len*step;
		a.z+=(t[id].z-a.z)/len*step;
		step*=0.98;
	}
	return res;
}
signed main(){
	while(~scanf("%d",&n),n){
		for(int i=1;i<=n;i++)	scanf("%lf %lf %lf",&t[i].x,&t[i].y,&t[i].z);
		printf("%.5f\n",solve());
	}
	return 0;
}
全部评论

相关推荐

评论
点赞
收藏
分享
牛客网
牛客企业服务