#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#define EPS 1e-8
using namespace std;
const int maxn = 5500;
double a[maxn][5];
int n;
struct point{
double x, y,z;
};
double ox,oy,r;
int sgn(double x)
{
if (fabs(x) < EPS)
return 0;
return x < 0 ? -1 : 1;
}
double get_distance(double x1,double y1,double x2,double y2)//两点之间的距离
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
void get(double ax, double ay, double bx, double by, double cx, double cy){
double x1 = ax-bx, y1 = ay-by;
double d1 = (ax*ax-bx*bx+ay*ay-by*by)/2;
double x2 = ax-cx, y2 = ay-cy;
double d2 = (ax*ax-cx*cx+ay*ay-cy*cy)/2;
ox = (d1*y2-y1*d2)/(x1*y2-y1*x2);
oy = (d2*x1-x2*d1)/(x1*y2-y1*x2);
r = get_distance(ox, oy, ax, ay);
}
//p表示定点, n表示顶点的个数, c代表最小覆盖圆圆心, r是半径
double min_cover_circle(int z,int y)//找最小覆盖圆(这里没有用全局变量p[], 因为是为了封装一个函数便于调用)
{
//random_shuffle(p, p + n);//随机函数,使用了之后使程序更快点,也可以不用
ox=a[1][z];
oy=a[1][y];
r = 0;
for (int i = 2; i <= n; i++)
{
if (sgn(get_distance(ox,oy,a[i][z],a[i][y]) - r) > 0)//如果p[i]在当前圆的外面, 那么以当前点为圆心开始找
{
ox=a[i][z];
oy=a[i][y];
//c = p[i];//圆心为当前点
r = 0;//这时候这个圆只包括他自己.所以半径为0
for (int j = 1; j < i; j++)//找它之前的所有点
{
if (sgn(get_distance(ox,oy,a[j][z],a[j][y]) - r) > 0)//如果之前的点有不满足的, 那么就是以这两点为直径的圆
{
ox = (a[i][z]+a[j][z]) / 2.0;
oy = (a[i][y]+a[j][y]) / 2.0;
r = get_distance(ox,oy,a[j][z],a[j][y]);
for (int k = 1; k < j; k++)
{
if (sgn(get_distance(ox,oy,a[k][z],a[k][y])-r) > 0)//找新作出来的圆之前的点是否还有不满足的, 如果不满足一定就是三个点都在圆上了
{
get(a[i][z],a[i][y],a[j][z],a[j][y],a[k][z],a[k][y]);
//r = get_distance(p[i], c);
}
}
}
}
}
}
return 2.0*r;
}
int main()
{
//point p[maxn];
//point c; double r;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
for(int j=1;j<=3;++j)
scanf("%lf", &a[i][j]);
random_shuffle(a+1, a+1 + n);
double nums=min(min_cover_circle(1,2),min(min_cover_circle(1,3),min_cover_circle(2,3)));
printf("%.10f\n",nums);
return 0;
}
07-19
07-19
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交