Problem:
Problem H:
Super Star
During a voyage of the starship Hakodate-maru (see Problem A), 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, stars 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
x
1
y
1
z
1
x
2
y
2
z
2
...
x
n
y
n
z
n
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 locations of
n
points are given by three-dimensional orthogonal coordinates: (
x
i
,
y
i
,
z
i
) (
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 ofthe 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
Output for the Sample Input
7.07107
34.64102

Submitted solutions:

code_snippet: //
//  main.cpp
//  poj 2069 Problem B : Super Star
//
//  Created by nuu_tong on 2018/4/20.
//  Copyright © 2018年 apple. All rights reserved.
//

#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;
struct Point
{
    double x,y,z;
};
Point p[35];
double dis[35];
int N;
double calDis(Point p1,Point p2)
{
    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)+(p1.z-p2.z)*(p1.z-p2.z));
}
int main()
{
    while(cin>>N&&N)
    {
        double ans=1e8;
        for(int i=0;i<N;i++)
            scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z);
        Point c;
        c.x=c.y=c.z=0;
        double step=100.0,len=0;
        int cur=0;
        while(step>1e-6)
        {
            for(int i=0;i<N;i++)//找出离当前位置最远的点
            {
                if(calDis(c,p[i])>calDis(c,p[cur]))
                    cur=i;
            }
            len=calDis(c,p[cur]);//
            ans=min(ans,len);
            c.x+=(p[cur].x-c.x)/len*step;//逐步向最远点移动
            c.y+=(p[cur].y-c.y)/len*step;
            c.z+=(p[cur].z-c.z)/len*step;
            step*=0.9994;
        }
        printf("%.5lf\n",ans);
    }
    return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 3380
final_rank: 12

code_snippet: #pragma region Macros

#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,fma,abm,mmx,avx,avx2")

#include <bits/extc++.h>
// #include <atcoder/all>
// using namespace atcoder;
using namespace std;
using namespace __gnu_pbds;

// #include <boost/multiprecision/cpp_dec_float.hpp>
// #include <boost/multiprecision/cpp_int.hpp>
// namespace mp = boost::multiprecision;
// using Bint = mp::cpp_int;
// using Bdouble = mp::number<mp::cpp_dec_float<256>>;
// Bdouble Beps = 0.00000000000000000000000000000001; // 1e-32
// const bool equals(Bdouble a, Bdouble b) { return mp::fabs(a - b) < Beps; }

#define pb emplace_back
#define int ll
#define endl '\n'
// #define unordered_map<int, int> gp_hash_table<int, int, custom_hash> 

#define sqrt __builtin_sqrtl
#define cbrt __builtin_cbrtl
#define hypot __builtin_hypotl

#define next asdnext
#define prev asdprev

using ll = long long;
using ld = long double;
const ld PI = acosl(-1);
const int INF = 1 << 30;
const ll INFL = 1LL << 61;
// const int MOD = 998244353;
const int MOD = 1000000007;

const ld EPS = 1e-10;
const bool equals(ld a, ld b) { return fabs((a) - (b)) < EPS; }

const vector<int> dx = {0, 1, 0, -1, 1, 1, -1, -1}; // → ↓ ← ↑ ↘ ↙ ↖ ↗
const vector<int> dy = {1, 0, -1, 0, 1, -1, -1, 1};

struct Edge {
    int from, to;
    double cost;
    Edge() : from(-1), to(-1), cost(-1) {}
    Edge(int to, double cost) : to(to), cost(cost) {}
    Edge(int from, int to, double cost) : from(from), to(to), cost(cost) {}
    bool operator ==(const Edge& e) {
        return this->from == e.from && this->to == e.to && this->cost == e.cost;
    }
    bool operator !=(const Edge& e) {
        return this->from != e.from or this->to != e.to or this->cost != e.cost;
    }
};
// struct Edge {
//     int from, to;
//     int cost;
//     Edge() : from(-1), to(-1), cost(-1) {}
//     Edge(int to, int cost) : to(to), cost(cost) {}
//     Edge(int from, int to, int cost) : from(from), to(to), cost(cost) {}
//     bool operator ==(const Edge& e) {
//         return this->from == e.from && this->to == e.to && this->cost == e.cost;
//     }
//     bool operator !=(const Edge& e) {
//         return this->from != e.from or this->to != e.to or this->cost != e.cost;
//     }
// };

chrono::system_clock::time_point start;
__attribute__((constructor))
void constructor() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(10);
    start = chrono::system_clock::now();
}

random_device seed_gen;
mt19937_64 rng(seed_gen());
uniform_int_distribution<int> dist_x(0, 1e9);
struct RNG {
    unsigned Int(unsigned l, unsigned r) {
        return dist_x(rng) % (r - l + 1) + l;
    }
    ld Double() {
        return ld(dist_x(rng)) / 1e9;
    }
} rnd;

using i64 = ll;
// using i64 = uint64_t;
// bit演算, x==0の場合は例外処理した方がよさそう. 区間は [l, r)
i64 lrmask(i64 l, i64 r) { return (1LL << r) - (1LL << l); }
i64 sub_bit(i64 x, i64 l, i64 r) { i64 b = x & ((1LL << r) - (1LL << l)); return b >> l; } // r溢れ可
i64 bit_width(i64 x) { return 64 - __builtin_clzll(x) + (x == 0); }

i64 popcount(i64 x) { return __builtin_popcountll(x); }
i64 popcount(i64 x, i64 l, i64 r) { return __builtin_popcountll(sub_bit(x, l, r)); }
i64 unpopcount(i64 x) { return bit_width(x) - __builtin_popcountll(x); }
i64 unpopcount(i64 x, i64 l, i64 r) { return r - l - __builtin_popcountll(sub_bit(x, l, r)); }
bool is_pow2(i64 x) { return __builtin_popcountll(x) == 1; }

i64 top_bit(i64 x) { return 63 - __builtin_clzll(x);} // 2^kの位 (x > 0)
i64 bot_bit(i64 x) { return __builtin_ctz(x);} // 2^kの位 (x > 0)
// i64 next_bit(i64 x, i64 k) { return 0; }
// i64 prev_bit(i64 x, i64 k) { return 0; }
// i64 kth_bit(i64 x, i64 k) { return 0; }
i64 MSB(i64 x) { if (x == 0) return 0; return 1LL << (63 - __builtin_clzll(x)); } // mask
i64 LSB(i64 x) { return (x & -x); } // mask

i64 countl_zero(i64 x) { return __builtin_clzll(x); }
i64 countl_one(i64 x) {
    i64 ret = 0, k = 63 - __builtin_clzll(x);
    while (k != -1 && (x & (1LL << k))) { k--; ret++; }
    return ret;
}
i64 countr_zero(i64 x) { return __builtin_ctzll(x); } // x==0のとき64が返ることに注意
i64 countr_one(i64 x) { i64 ret = 0; while (x & 1) { x >>= 1; ret++; } return ret; }

i64 floor_log2(i64 x) { if (x == 0) return 0; return 63 - __builtin_clzll(x); }
i64 bit_floor(i64 x) { if (x == 0) return 0; return 1LL << (63 - __builtin_clzll(x)); } // MSBと同じ
i64 ceil_log2(i64 x) { if (x == 0) return 0; return 64 - __builtin_clzll(x - 1); }
i64 bit_ceil(i64 x) { if (x == 0) return 0; return 1LL << (64 - __builtin_clzll(x - 1)); }

i64 rotl(i64 x, i64 k) { // 有効bit内でrotate. オーバーフロー注意
    i64 w = bit_width(x); k %= w;
    return ((x << k) | (x >> (w - k))) & ((1LL << w) - 1);
}
// i64 rotl(i64 x, i64 l, i64 m, i64 r) {}
i64 rotr(i64 x, i64 k) {
    i64 w = bit_width(x); k %= w;
    return ((x >> k) | (x << (w - k))) & ((1LL << w) - 1);
}
// i64 rotr(i64 x, i64 l, i64 m, i64 r) {}
i64 bit_reverse(i64 x) { // 有効bit内で左右反転
    i64 r = 0, w = bit_width(x);
    for (i64 i = 0; i < w; i++) r |= ((x >> i) & 1) << (w - i - 1);
    return r;
}
// i64 bit_reverse(i64 x, i64 l, i64 r) { return 0; }

bool is_palindrome(i64 x) { return x == bit_reverse(x); }
bool is_palindrome(i64 x, i64 l, i64 r) { i64 b = sub_bit(x, l, r); return b == bit_reverse(b); }
i64 concat(i64 a, i64 b) { return (a << bit_width(b)) | b; } // オーバーフロー注意
i64 erase(i64 x, i64 l, i64 r) { return x>>r<<l | x&(1LL<<l - 1); } // [l, r) をカット

i64 hamming(i64 a, i64 b) { return __builtin_popcountll(a ^ b); }
i64 hamming(i64 a, i64 b, i64 l, i64 r) { return __builtin_popcountll(sub_bit(a, l, r) ^ sub_bit(b, l, r)); }
i64 compcount(i64 x) { return (__builtin_popcountll(x ^ (x >> 1)) + (x & 1)) / 2; }
i64 compcount2(i64 x) { return compcount(x & (x >> 1)); } // 長さ2以上の連結成分の個数
i64 adjacount(i64 x) { return __builtin_popcountll(x & (x >> 1)); } // 隣接する1のペアの個数

i64 next_combination(i64 x) {
    i64 t = x | (x - 1); return (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctz(x) + 1));
}


__int128_t POW(__int128_t x, int n) {
    __int128_t ret = 1;
    assert(n >= 0);
    if (x == 1 or n == 0) ret = 1;
    else if (x == -1 && n % 2 == 0) ret = 1; 
    else if (x == -1) ret = -1; 
    else if (n % 2 == 0) {
        assert(x < INFL);
        ret = POW(x * x, n / 2);
    } else {
        assert(x < INFL);
        ret = x * POW(x, n - 1);
    }
    return ret;
}
int per(int x, int y) { // x = qy + r (0 <= r < y) を満たすq
    assert(y != 0);
    if (x >= 0 && y > 0) return x / y;
    if (x >= 0 && y < 0) return x / y - (x % y < 0);
    if (x < 0 && y < 0) return x / y + (x % y < 0);
    return x / y - (x % y < 0); //  (x < 0 && y > 0) 
}
int mod(int x, int y) { // x = qy + r (0 <= r < y) を満たすr
    assert(y != 0);
    if (x >= 0) return x % y;
    __int128_t ret = x % y; // (x < 0)
    ret += (__int128_t)abs(y) * INFL;
    ret %= abs(y);
    return ret;
}
int floor(int x, int y) { // (ld)x / y 以下の最大の整数
    assert(y != 0);
    if (y < 0) x = -x, y = -y;
    return x >= 0 ? x / y : (x + 1) / y - 1;
}
int ceil(int x, int y) { // (ld)x / y 以上の最小の整数
    assert(y != 0);
    if (y < 0) x = -x, y = -y;
    return x > 0 ? (x - 1) / y + 1 : x / y;
}
int round(int x, int y) {
    assert(y != 0);
    return (x * 2 + y) / (y * 2);
}
int round(int x, int y, int k) { // (ld)(x/y)を10^kの位に関して四捨五入
    assert(y != 0); // TODO
    return INF;
}
int round2(int x, int y) { // 五捨五超入 // 未verify
    assert(y != 0);
    if (y < 0) y = -y, x = -x;
    int z = z / y;
    if ((z * 2 + 1) * y <= y * 2) z++;
    return z;
}
// int round(ld x, int k) { // xを10^kの位に関して四捨五入
// }
// int floor(ld x, int k) { // xを10^kの位に関してflooring
// }
// int ceil(ld x, int k) { // xを10^kの位に関してceiling
// }
// int kth(int x, int y, int k) { // x / yの10^kの位の桁
// }
int floor(ld x, ld y) { // 誤差対策TODO
    assert(!equals(y, 0));
    return floor(x / y);
    // floor(x) = ceil(x - 1) という話も
}
int ceil(ld x, ld y) { // 誤差対策TODO // ceil(p/q) = -floor(-(p/q))らしい
    assert(!equals(y, 0));
    return ceil(x / y);
    // ceil(x) = floor(x + 1)
}
int perl(ld x, ld y) { // x = qy + r (0 <= r < y, qは整数) を満たす q
    // 未verify. 誤差対策TODO. EPS外してもいいかも。
    assert(!equals(y, 0));
    if (x >= 0 && y > 0) return floor(x / y)+EPS;
    if (x >= 0 && y < 0) return -floor(x / fabs(y));
    if (x < 0 && y < 0) return floor(x / y) + (x - floor(x/y)*y < -EPS);
    return floor(x / y) - (x - floor(x/y)*y < -EPS); //  (x < 0 && y > 0) 
}
ld modl(ld x, ld y) { // x = qy + r (0 <= r < y, qは整数) を満たす r
    // 未verify. 誤差対策TODO. -0.0が返りうる。
    assert(!equals(y, 0));
    if (x >= 0) return x - fabs(y)*fabs(per(x, y));
    return x - fabs(y)*floor(x, fabs(y));
}
int seisuu(ld x) { return (int)x; } // 整数部分. 誤差対策TODO
int modf(ld x) {
	if (x < 0) return ceill(x);
	else return floorl(x);
}
// 正なら+EPS, 負なら-EPSしてから、文字列に直して小数点以下を捨てる?
int seisuu(int x, int y) {
    assert(y != 0);
    return x / y;
}
int seisuu(ld x, ld y) { // 誤差対策TODO
    assert(!equals(y, 0));
    return (int)(x / y);
}

template <class T> pair<T, T> max(const pair<T, T> &a, const pair<T, T> &b) {
    if (a.first > b.first or a.first == b.first && a.second > b.second) return a;
    return b;
}
template <class T> pair<T, T> min(const pair<T, T> &a, const pair<T, T> &b) {
    if (a.first < b.first or a.first == b.first && a.second < b.second) return a;
    return b;
}

template <class T> bool chmax(T &a, const T& b) {
    if (a < b) { a = b; return true; } return false;
}
template <class T> bool chmin(T &a, const T& b) {
    if (a > b) { a = b; return true; } return false;
}
template <class T> T mid(T a, T b, T c) { // 誤差対策TODO
    return a + b + c - max({a, b, c}) - min({a, b, c});
}
template <class T> void Sort(T &a, T &b, bool rev = false) { 
    if (rev == false) {  // TODO テンプレート引数
        if (a > b) swap(a, b);
    } else {
        if (b > a) swap(b, a);
    }
}
template <class T> void Sort(T &a, T &b, T &c, bool rev = false) {
    if (rev == false) { 
        if (a > b) swap(a, b); if (a > c) swap(a, c); if (b > c) swap(b, c);
    } else {
        if (c > b) swap(c, b); if (c > a) swap(c, a); if (b > a) swap(b, a);
    }
}
template <class T> void Sort(T &a, T &b, T &c, T &d, bool rev = false) {
    if (rev == false) { 
        if (a > b) swap(a, b); if (a > c) swap(a, c);  if (a > d) swap(a, d);
        if (b > c) swap(b, c); if (b > d) swap(b, d); if (c > d) swap(c, d);
    } else {
        if (d > c) swap(d, c); if (d > b) swap(d, b); if (d > a) swap(d, a);
        if (c > b) swap(c, b); if (c > a) swap(c, a); if (b > a) swap(b, a);
    }
}

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

class Compress {
public:
    int sz = 0;
    // gp_hash_table<int, int, custom_hash> Z, UZ;
    unordered_map<int, int> Z;    // 元の値 -> 圧縮した値
    unordered_map<int, int> UZ;   // 圧縮した値 -> 元の値

    Compress(const vector<int> &V, int base = 0) {
        this->sz = base;
        set<int> s(V.begin(), V.end());

        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
    
    Compress(const vector<int> &V1, const vector<int> &V2, int base = 0) {
        this->sz = base;
        vector<int> V3 = V2;
        V3.insert(V3.end(), V1.begin(), V1.end());
        set<int> s(V3.begin(), V3.end());

        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }

    Compress(const vector<int> &V1, const vector<int> &V2, const vector<int> &V3, int base = 0) {
        this->sz = base;
        vector<int> V4 = V1;
        V4.insert(V4.end(), V2.begin(), V2.end());
        V4.insert(V4.end(), V3.begin(), V3.end());
        set<int> s(V4.begin(), V4.end());

        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }

    Compress(const vector<int> &V1, const vector<int> &V2,
            const vector<int> &V3, const vector<int> &V4, int base = 0) {
        this->sz = base;
        vector<int> V5 = V1;
        V5.insert(V5.end(), V2.begin(), V2.end());
        V5.insert(V5.end(), V3.begin(), V3.end());
        V5.insert(V5.end(), V4.begin(), V4.end());
        set<int> s(V5.begin(), V5.end());

        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }

    vector<int> zip(const vector<int> &V) {
        vector<int> ret = V;
        for (int i = 0; i < (int)V.size(); i++) {
            ret[i] = Z[ret[i]];
        }
        return ret;
    }

    vector<int> unzip(const vector<int> &V) {
        vector<int> ret = V;
        for (int i = 0; i < (int)V.size(); i++) {
            ret[i] = UZ[ret[i]];
        }
        return ret;
    }

    int size() { return sz; }

    int encode(int x) { return Z[x]; }
    int decode(int x) {
        if (UZ.find(x) == UZ.end()) return -1; // xが元の配列に存在しないとき
        return UZ[x];
    }
};

class UnionFind {
public:
	UnionFind() = default;
    UnionFind(int N) : par(N), sz(N, 1) {
        iota(par.begin(), par.end(), 0);
    }
	int root(int x) {
		if (par[x] == x) return x;
		return (par[x] = root(par[x]));
	}
	bool unite(int x, int y) {
		int rx = root(x);
		int ry = root(y);
        if (rx == ry) return false;
		if (sz[rx] < sz[ry]) swap(rx, ry);
		sz[rx] += sz[ry];
		par[ry] = rx;
        return true;
	}
	bool issame(int x, int y) { return (root(x) == root(y)); }
	int size(int x) { return sz[root(x)]; }
    vector<vector<int>> groups(int N) {
        vector<vector<int>> G(N);
        for (int x = 0; x < N; x++) {
            G[root(x)].push_back(x);
        }
		G.erase( remove_if(G.begin(), G.end(),
            [&](const vector<int>& V) { return V.empty(); }), G.end());
        return G;
    }
private:
	vector<int> par, sz;
};

template<typename T>
struct BIT {
    int N;             // 要素数
    vector<T> bit[2];  // データの格納先
    BIT(int N_, int x = 0) {
        N = N_ + 1;
        bit[0].assign(N, 0); bit[1].assign(N, 0);
        if (x != 0) {
            for (int i = 0; i < N; i++) add(i, x);
        }
    }
    BIT(const vector<int> &A) {
        N = A.size() + 1;
        bit[0].assign(N, 0); bit[1].assign(N, 0);
        for (int i = 0; i < (int)A.size(); i++) add(i, A[i]);
    }
    void add_sub(int p, int i, T x) {
        while (i < N) { bit[p][i] += x; i += (i & -i); }
    }
    void add(int l, int r, T x) {
        add_sub(0, l + 1, -x * l); add_sub(0, r + 1, x * r);
        add_sub(1, l + 1, x); add_sub(1, r + 1, -x);
    }
    void add(int i, T x) { add(i, i + 1, x); }
    T sum_sub(int p, int i) {
        T ret = 0;
        while (i > 0) { ret += bit[p][i]; i -= (i & -i); }
        return ret;
    }
    T sum(int i) { return sum_sub(0, i) + sum_sub(1, i) * i; }
    T sum(int l, int r) { return sum(r) - sum(l); }
    T get(int i) { return sum(i, i + 1); }
    void set(int i, T x) { T s = get(i); add(i, -s + x); }
};

template<int mod> class Modint {
public:
    int val = 0;
    Modint(int x = 0) { while (x < 0) x += mod; val = x % mod; }
    Modint(const Modint &r) { val = r.val; }

    Modint operator -() { return Modint(-val); } // 単項
    Modint operator +(const Modint &r) { return Modint(*this) += r; }
    Modint operator +(const int &q) { Modint r(q); return Modint(*this) += r; }
    Modint operator -(const Modint &r) { return Modint(*this) -= r; }
    Modint operator -(const int &q) { Modint r(q); return Modint(*this) -= r; }
    Modint operator *(const Modint &r) { return Modint(*this) *= r; }
    Modint operator *(const int &q) { Modint r(q); return Modint(*this) *= r; }
    Modint operator /(const Modint &r) { return Modint(*this) /= r; }
    Modint operator /(const int &q) { Modint r(q); return Modint(*this) /= r; }
    
    Modint& operator ++() { val++; if (val >= mod) val -= mod; return *this; } // 前置
    Modint operator ++(signed) { ++*this; return *this; } // 後置
    Modint& operator --() { val--; if (val < 0) val += mod; return *this; }
    Modint operator --(signed) { --*this; return *this; }
    Modint &operator +=(const Modint &r) { val += r.val; if (val >= mod) val -= mod; return *this; }
    Modint &operator +=(const int &q) { Modint r(q); val += r.val; if (val >= mod) val -= mod; return *this; }
    Modint &operator -=(const Modint &r) { if (val < r.val) val += mod; val -= r.val; return *this; }
    Modint &operator -=(const int &q) { Modint r(q);  if (val < r.val) val += mod; val -= r.val; return *this; }
    Modint &operator *=(const Modint &r) { val = val * r.val % mod; return *this; }
    Modint &operator *=(const int &q) { Modint r(q); val = val * r.val % mod; return *this; }
    Modint &operator /=(const Modint &r) {
        int a = r.val, b = mod, u = 1, v = 0;
        while (b) {int t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v);}
        val = val * u % mod; if (val < 0) val += mod;
        return *this;
    }
    Modint &operator /=(const int &q) {
        Modint r(q); int a = r.val, b = mod, u = 1, v = 0;
        while (b) {int t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v);}
        val = val * u % mod; if (val < 0) val += mod;
        return *this;
    }
    bool operator ==(const Modint& r) { return this -> val == r.val; }
    bool operator <(const Modint& r) { return this -> val < r.val; }
    bool operator >(const Modint& r) { return this -> val > r.val; }
    bool operator !=(const Modint& r) { return this -> val != r.val; }
};

using mint = Modint<MOD>;

istream &operator >>(istream &is, mint& x) {
    int t; is >> t; x = t; return (is);
}
ostream &operator <<(ostream &os, const mint& x) {
    return os << x.val;
}
mint modpow(const mint &x, int n) {
    if (n < 0) return (mint)1 / modpow(x, -n); // 未verify
    assert(n >= 0);
    if (n == 0) return 1;
    mint t = modpow(x, n / 2);
    t = t * t;
    if (n & 1) t = t * x;
    return t;
}

int modpow(__int128_t x, int n, int mod) {
    assert(n >= 0 && mod > 0); // TODO: n <= -1
    __int128_t ret = 1;
    while (n > 0) {
        if (n % 2 == 1) ret = ret * x % mod;
        x = x * x % mod;
        n /= 2;
    }
    return ret;
}
int modinv(__int128_t x, int mod) {
    assert(mod > 0);
    // assert(x > 0);
    if (x == 1 or x == 0) return 1;
    return mod - modinv(mod % x, mod) * (mod / x) % mod;
}

istream &operator >>(istream &is, __int128_t& x) {
    string S; is >> S;
    __int128_t ret = 0;
    int f = 1;
    if (S[0] == '-') f = -1; 
    for (int i = 0; i < S.length(); i++)
        if ('0' <= S[i] && S[i] <= '9')
            ret = ret * 10 + S[i] - '0';
    x = ret * f;
    return (is);
}
ostream &operator <<(ostream &os, __int128_t x) {
    ostream::sentry s(os);
    if (s) {
        __uint128_t tmp = x < 0 ? -x : x;
        char buffer[128]; char *d = end(buffer);
        do {
            --d; *d = "0123456789"[tmp % 10]; tmp /= 10;
        } while (tmp != 0);
        if (x < 0) { --d; *d = '-'; }
        int len = end(buffer) - d;
        if (os.rdbuf()->sputn(d, len) != len) os.setstate(ios_base::badbit);
    }
    return os;
}

__int128_t stoll(string &S) {
    __int128_t ret = 0; int f = 1;
    if (S[0] == '-') f = -1; 
    for (int i = 0; i < S.length(); i++)
        if ('0' <= S[i] && S[i] <= '9') ret = ret * 10 + S[i] - '0';
    return ret * f;
}
__int128_t gcd(__int128_t a, __int128_t b) { return b ? gcd(b, a % b) : a; }
__int128_t lcm(__int128_t a, __int128_t b) {
    return a / gcd(a, b) * b;
    // lcmが__int128_tに収まる必要あり
}

string to_string(ld x, int k) { // xの小数第k位までをstring化する
    assert(k >= 0);
    stringstream ss;
    ss << setprecision(k + 2) << x;
    string s = ss.str();
    if (s.find('.') == string::npos) s += '.';
    int pos = s.find('.');
    for (int i = 0; k >= (int)s.size() - 1 - pos; i++) s += '0';
    s.pop_back();
    if (s.back() == '.') s.pop_back();
    return s;

    // stringstream ss; // 第k+1位を四捨五入して第k位まで返す
    // ss << setprecision(k + 1) << x;
    // string s = ss.str();
    // if (s.find('.') == string::npos) s += '.';
    // int pos = s.find('.');
    // for (int i = 0; k > (int)s.size() - 1 - pos; i++) s += '0';
    // if (s.back() == '.') s.pop_back();
    // return s;
}
string to_string(__int128_t x) {
    string ret = "";
    if (x < 0) { ret += "-"; x *= -1; }
    while (x) { ret += (char)('0' + x % 10); x /= 10; }
    reverse(ret.begin(), ret.end());
    return ret;
}
string to_string(char c) { string s = ""; s += c; return s; }

template<class T> size_t HashCombine(const size_t seed,const T &v) {
    return seed^(hash<T>()(v)+0x9e3779b9+(seed<<6)+(seed>>2));
}
template<class T,class S> struct hash<pair<T,S>>{
    size_t operator()(const pair<T,S> &keyval) const noexcept {
        return HashCombine(hash<T>()(keyval.first), keyval.second);
    }
};
template<class T> struct hash<vector<T>>{
    size_t operator()(const vector<T> &keyval) const noexcept {
        size_t s=0;
        for (auto&& v: keyval) s=HashCombine(s,v);
        return s;
    }
};
template<int N> struct HashTupleCore{
    template<class Tuple> size_t operator()(const Tuple &keyval) const noexcept{
        size_t s=HashTupleCore<N-1>()(keyval);
        return HashCombine(s,get<N-1>(keyval));
    }
};
template <> struct HashTupleCore<0>{
    template<class Tuple> size_t operator()(const Tuple &keyval) const noexcept{ return 0; }
};
template<class... Args> struct hash<tuple<Args...>>{
    size_t operator()(const tuple<Args...> &keyval) const noexcept {
        return HashTupleCore<tuple_size<tuple<Args...>>::value>()(keyval);
    }
};

vector<mint> _fac, _finv, _inv;
void COMinit(int N) {
    _fac.resize(N + 1); _finv.resize(N + 1);  _inv.resize(N + 1);
    _fac[0] = _fac[1] = 1; _finv[0] = _finv[1] = 1; _inv[1] = 1;
    for (int i = 2; i <= N; i++) {
        _fac[i] = _fac[i-1] * mint(i);
        _inv[i] = -_inv[MOD % i] * mint(MOD / i);
        _finv[i] = _finv[i - 1] * _inv[i];
    }
}

mint FAC(int N) {
    if (N < 0) return 0; return _fac[N];
}
mint COM(int N, int K) {
    if (N < K) return 0; if (N < 0 or K < 0) return 0;
    return _fac[N] * _finv[K] * _finv[N - K];
}
mint PERM(int N, int K) {
    if (N < K) return 0; if (N < 0 or K < 0) return 0;
    return _fac[N] *  _finv[N - K];
}
mint NHK(int N, int K) { // initのサイズに注意
    if (N == 0 && K == 0)  return 1;
    return COM(N + K - 1, K);
}

#pragma endregion

class Point3d {
public:
    double x, y, z;

    Point3d(double x = 0, double y = 0, double z = 0) : x(x), y(y), z(z) {}

    Point3d operator+(const Point3d& a) {
        return Point3d(x + a.x, y + a.y, z + a.z);
    }
    Point3d operator-(const Point3d& a) {
        return Point3d(x - a.x, y - a.y, z - a.z);
    }
    Point3d operator*(const double& d) {
        return Point3d(x * d, y * d, z * d);
    }
    Point3d operator/(const double& d) {
        return Point3d(x / d, y / d, z / d);
    }

    bool operator<(const Point3d& p) const {
        if (!equals(x, p.x)) return x < p.x;
        if (!equals(y, p.y)) return y < p.y;
        if (!equals(z, p.z)) return z < p.z;
        return false;
    }

    bool operator==(const Point3d& p) const {
        return equals(x, p.x) && equals(y, p.y) && equals(z, p.z);
    }

    friend istream& operator>>(istream& is, Point3d& p) {
		is >> p.x >> p.y >> p.z;
		return is;
	}
	friend ostream& operator<<(ostream& os, Point3d& p) {
		os << p.x << " " << p.y << " " << p.z;
		return os;
	}
};

int sign(double x) { return x < -EPS ? -1 : x > EPS; } // -1(負)/0/1(正)

struct Segment3d {
    Point3d p[2], d; // pは端点、dは向き
    Segment3d(Point3d p1 = Point3d(), Point3d p2 = Point3d()) {
        p[0] = p1, p[1] = p2;
        d = p[1] - p[0];
    }
    bool operator==(const Segment3d& S) const {
        return (p[0] == S.p[0] && p[1] == S.p[1]) || (p[0] == S.p[1] && p[1] == S.p[0]);
    }
};

using Line3d = Segment3d;
using Vector3d = Point3d;

bool is_parallel(Vector3d v1, Vector3d v2) {
    if (equals(v1.x*v2.y, v1.y*v2.x) && 
        equals(v1.y*v2.z, v1.z*v2.y) &&
        equals(v1.z*v2.x, v1.x*v2.z)) return true;
    return false;
}
bool is_orthogonal(Vector3d v1, Vector3d v2) {
    if (equals(v1.x*v2.x + v1.y*v2.y + v1.z*v2.z, 0)) return true;
    return false;
}

bool is_parallel(Line3d &l, Line3d &m) {
    return is_parallel(l.p[1] - l.p[0], m.p[1] - m.p[0]);
}
bool is_orthogonal(Line3d &l, Line3d &m) {
    return is_orthogonal(l.p[1] - l.p[0], m.p[1] - m.p[0]);
}

ostream& operator<<(ostream& os, const Point3d& p) {
    return os << "(" << p.x << "," << p.y << "," << p.z << ")";
}

ostream& operator<<(ostream& os, const Segment3d& S) {
    return os << "(" << S.p[0] << "," << S.p[1] << ")";
}

double dot(const Point3d& a, const Point3d& b) {
    return a.x * b.x + a.y * b.y + a.z * b.z;
}

Vector3d cross(const Point3d& a, const Point3d& b) {
    return Vector3d(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
}

inline double norm(const Point3d& p) {
    return p.x * p.x + p.y * p.y + p.z * p.z;
}

inline double abs(const Point3d& p) {
    return sqrt(norm(p));
}

double rad_to_deg(double r) { return (r * 180.0 / PI); }
double deg_to_rad(double d) { return (d * PI / 180.0); }

double angle(Point3d a, Point3d b) {
    double costheta = dot(a, b) / norm(a) / norm(b);
    return acos(max<double>(-1.0, min<double>(1.0, costheta)));
}

Point3d rotateccw90(Point3d a) { return Point3d(-a.y, a.x); }
Point3d rotatecw90(Point3d a) { return Point3d(a.y, -a.x); }
Point3d rotateccw(Point3d a, double t) { return Point3d(a.x * cos(t) - a.y * sin(t), a.x * sin(t) + a.y * cos(t)); }
Point3d rotatecw(Point3d a, double t) { return Point3d(a.x * cos(t) + a.y * sin(t), -a.x * sin(t) + a.y * cos(t)); }

double distanceLP(Line3d L, Point3d p) {
    return abs(cross(L.p[1] - L.p[0], p - L.p[0])) / abs(L.p[1] - L.p[0]);
}

double dist(Point3d p1, Point3d p2) {
    return sqrt(norm(p1 - p2));
}

Point3d project(Segment3d S, Point3d p) {
    Vector3d base = S.p[1] - S.p[0];
    double t = dot(p - S.p[0], base) / norm(base);
    return S.p[0] + base * t;
}

Point3d reflect(Segment3d S, Point3d p) {
    return p + (project(S, p) - p) * 2.0;
}

bool on_line3d(Line3d L, Point3d p) {
    return equals(abs(cross(L.p[1] - p, L.p[0] - p)), 0);
}

bool on_segment3d(Segment3d S, Point3d p) {
    if (!on_line3d(S, p)) return false;
    double dist[3] = {abs(S.p[1] - S.p[0]), abs(p - S.p[0]), abs(p - S.p[1])};
    return on_line3d(S, p) && equals(dist[0], dist[1] + dist[2]);
}

double distanceSP(Segment3d S, Point3d p) {
    Point3d r = project(S, p);
    if (on_segment3d(S, r)) return abs(p - r);
    return min<double>(abs(S.p[0] - p), abs(S.p[1] - p));
}

struct Sphere {
    Point3d c;
    double r;
    Sphere() {}
    Sphere(Point3d c, double r) : c(c), r(r) {}
};

// https://github.com/ShahjalalShohag/code-library/blob/main/Geometry/Geometry%203D.cpp
Sphere smallest_enclosing_sphere(vector<Point3d> p) {
    int n = p.size();
    Point3d c(0, 0, 0);
    for(int i = 0; i < n; i++) c = c + p[i];
    c = c / n;

    double ratio = 0.1;
    int pos = 0;
    int it = 100000;
    while (it--) {
        pos = 0;
        for (int i = 1; i < n; i++) {
            if(dot(c - p[i], c - p[i]) > dot(c - p[pos], c - p[pos])) pos = i;
        }
        c = c + (p[pos] - c) * ratio;
        ratio *= 0.998;
    }
    return Sphere(c, abs(c - p[pos]));
}

signed main() {
    int N;
    while (cin >> N, N) {
        vector<Point3d> P(N);
        for (int i = 0; i < N; i++) cin >> P[i];

        Sphere S = smallest_enclosing_sphere(P);
        cout << S.r << endl;
    }
}
accuracy: 1
time_ms: 180
memory_kb: 3528
final_rank: 13

code_snippet: #include <iostream>
#include <vector>
#include <cmath>
#include <numeric>
#include <cfloat>
#include <climits>
#include <algorithm>
#include <iomanip>
#include <queue>
#include <unordered_set>
#include <unordered_map>
#include <string>
#include <tuple>
#include <set>
#include <stack>
#include <array>
#include <cassert>
constexpr double EPSILON = 1e-8;
struct Point {
	double x, y, z;
	double distance(const Point& other) const;
};
struct Angle {
	double sin, cos;
	static Angle from_cos(const double cos) {
		return Angle{ std::sqrt(1 - cos * cos), cos };
	}
	Angle to_under180() const {
		return (sin >= 0) ? *this : Angle{ -sin, cos };
	}
};
struct Vector {
	double dx, dy, dz;
	double length() const {
		return std::sqrt(dx * dx + dy * dy + dz * dz);
	}
	double dot(const Vector& other) const {
		return dx * other.dx + dy * other.dy + dz * other.dz;
	}
	Vector cross(const Vector& other) const {
		return Vector{
			dy * other.dz - dz * other.dy,
			dz * other.dx - dx * other.dz,
			dx * other.dy - dy * other.dx
		};
	}
	Angle angle_between(const Vector& other) const {
		const auto len = length() * other.length();
		return Angle{ cross(other).length() / len, dot(other) / len };
	}
};
Vector operator*(const Vector& vec, const double scale) {
	return Vector{ vec.dx * scale, vec.dy * scale, vec.dz * scale };
}
Vector operator*(const double scale, const Vector& vec) {
	return Vector{ vec.dx * scale, vec.dy * scale, vec.dz * scale };
}
Vector operator+(const Vector& a, const Vector& b) {
	return Vector{ a.dx + b.dx, a.dy + b.dy, a.dz + b.dz };
}
Point operator+(const Vector& vec, const Point& p) {
	return Point{ p.x + vec.dx, p.y + vec.dy, p.z + vec.dz };
}
Point operator+(const Point& p, const Vector& vec) {
	return vec + p;
}
Vector operator-(const Point& a, const Point& b) {
	return Vector{ a.x - b.x, a.y - b.y, a.z - b.z };
}
struct Triangle {
	std::array<Point, 3> vertex;
	Angle angle_a() const {
		return (vertex[1] - vertex[0]).angle_between(vertex[2] - vertex[0]).to_under180();
	}
	Angle angle_b() const {
		return (vertex[2] - vertex[1]).angle_between(vertex[0] - vertex[1]).to_under180();
	}
	Angle angle_c() const {
		return (vertex[0] - vertex[2]).angle_between(vertex[1] - vertex[2]).to_under180();
	}
	double len_a() const {
		return (vertex[2] - vertex[1]).length();
	}
	double len_b() const {
		return (vertex[0] - vertex[2]).length();
	}
	double len_c() const {
		return (vertex[1] - vertex[0]).length();
	}
	Point circumcenter() const {
		const auto A = angle_a();
		const auto B = angle_b();
		const auto C = angle_c();
		const auto a = len_a();
		const auto b = len_b();
		const auto c = len_c();
		const auto vec_a = vertex[0] - Point{ 0, 0 };
		const auto vec_b = vertex[1] - Point{ 0, 0 };
		const auto vec_c = vertex[2] - Point{ 0, 0 };
		return Point{ 0, 0 } + (vec_a * a * A.cos + vec_b * b * B.cos + vec_c * c * C.cos) * (1 / (a * A.cos + b * B.cos + c * C.cos));
	}
};
std::vector<double>& operator+=(std::vector<double>& dest, const std::vector<double>& add) {
	for (auto i = 0; i < dest.size(); ++i) {
		dest[i] += add[i];
	}
	return dest;
}
std::vector<double>& operator-=(std::vector<double>& dest, const std::vector<double>& sub) {
	for (auto i = 0; i < dest.size(); ++i) {
		dest[i] -= sub[i];
	}
	return dest;
}
std::vector<double>& operator*=(std::vector<double>& dest, const double scale) {
	for (auto& a : dest) a *= scale;
	return dest;
}
void remove(std::vector<double>& dest, const std::vector<double>& vec, const int key) {
	const auto ratio = dest[key] / vec[key];
	for (auto i = 0; i < dest.size(); ++i) {
		dest[i] -= vec[i] * ratio;
	}
}
bool solve(std::vector<std::vector<double>> &matrix) {
	for (auto i = 0; i < matrix.size(); ++i) {
		int key{ -1 };
		for (auto j = i; j < matrix.size(); ++j) {
			if (std::abs(matrix[j][i]) > DBL_EPSILON) {
				key = j; break;
			}
		}
		if (key < 0) return false;
		if (key != i) matrix[i] += matrix[key];
		matrix[i] *= 1 / matrix[i][i];
		for (auto j = 0; j < matrix.size(); ++j) {
			if (i == j) continue;
			remove(matrix[j], matrix[i], i);
		}
	}
	return true;
}
std::vector<double> circle_equation(const Point p) {
	return { -2 * p.x, -2 * p.y, -2 * p.z, -p.x * p.x - p.y * p.y - p.z * p.z };
}
struct Circle {
	Point center;
	double radius;
	bool contains(const Point& point) const {
		return point.distance(center) < radius + EPSILON;
	}
};
bool is_on_same_plane(const Point &a, const Point &b, const Point &c, const Point &d) {
	return std::abs((a - b).cross(c - b).dot(d - b)) < EPSILON;
}
bool is_on_same_line(const Point &a, const Point &b, const Point &c) {
	return std::abs((a - b).cross(c - b).length()) < EPSILON;
}
Circle calc_circle(const Point a, const Point b) {
	const Point center{ (a.x + b.x) / 2, (a.y + b.y) / 2, (a.z + b.z) / 2 };
	const auto radius = center.distance(a);
	//assert(std::abs(radius - center.distance(b)) < EPSILON);
	return Circle{ center, radius };
}
Circle calc_circle(const Point a, const Point b, const Point c) {
	if (is_on_same_line(a, b, c)) return calc_circle(a, b);
	const Triangle triangle{ a, b, c };
	const auto center = triangle.circumcenter();
	const auto radius = center.distance(a);
	//assert(std::abs(radius - center.distance(b)) < EPSILON);
	//assert(std::abs(radius - center.distance(c)) < EPSILON);
	return Circle{ center, radius };
}
Circle calc_circle(const Point a, const Point b, const Point c, const Point d) {
	if (is_on_same_plane(a, b, c, d)) { return calc_circle(a, b, c); }
	std::vector<std::vector<double>> equation{ circle_equation(a), circle_equation(b), circle_equation(c) };
	equation[0] -= equation[1];
	equation[1] -= equation[2];
	equation[2] -= circle_equation(d);
	if (!solve(equation)) {
		throw 0;
	}
	const Point center{ equation[0].back(), equation[1].back(), equation[2].back() };
	const auto radius = center.distance(a);
	//assert(std::abs(radius - center.distance(b)) < EPSILON);
	//assert(std::abs(radius - center.distance(c)) < EPSILON);
	//assert(std::abs(radius - center.distance(d)) < EPSILON);
	return Circle{ center, radius };
}
Circle calc_circle(const std::vector<Point>& points) {
	switch (points.size()) {
	case 2: return calc_circle(points[0], points[1]);
	case 3: return calc_circle(points[0], points[1], points[2]);
	case 4: return calc_circle(points[0], points[1], points[2], points[3]);
	default: throw 0;
	}
}
double min_radius(const Point center, const std::vector<Point>& points) {
	double result = 0;
	for (const auto &p : points) {
		result = std::max(result, center.distance(p));
	}
	return result;
}
double min_radius(const int current, const std::vector<Point>& points, std::vector<Point>& stack) {
	if (stack.size() == 4) {
		return min_radius(calc_circle(stack).center, points);
	}
	else if (current == points.size()) {
		return DBL_MAX;
	}
	else if (stack.size() >= 2) {
		double result = min_radius(calc_circle(stack).center, points);
		result = std::min(result, min_radius(current + 1, points, stack));
		stack.push_back(points[current]);
		result = std::min(result, min_radius(current + 1, points, stack));
		stack.pop_back();
		return result;
	}
	else {
		double result = min_radius(current + 1, points, stack);
		stack.push_back(points[current]);
		result = std::min(result, min_radius(current + 1, points, stack));
		stack.pop_back();
		return result;
	}
}
int main() {
	while (true) {
		int n; std::cin >> n;
		if (n == 0) break;
		std::vector<Point> points(n);
		for (auto& p : points) std::cin >> p.x >> p.y >> p.z;
		std::vector<Point> stack;
		const auto result = min_radius(0, points, stack);
		std::cout << std::setprecision(5) << std::fixed << std::round(result * 100000) / 100000 << '\n';
	}
}

double Point::distance(const Point& other) const
{
	return (*this - other).length();
}
accuracy: 1
time_ms: 80
memory_kb: 3396
final_rank: 11

code_snippet: #include<iostream>
#include<cmath>

using namespace std;

#define S(X) ((X)*(X))

double dsq(double x,double y,double z,double xx,double yy,double zz){
  return S(xx-x)+S(yy-y)+S(zz-z);
}

int main(){
  for(int n;cin>>n,n;){
    double x[30],y[30],z[30];
    for(int i=0;i<n;i++){
      cin>>x[i]>>y[i]>>z[i];
    }
    double cx=0,cy=0,cz=0;
    double f;
    for(double d=10;d>1e-9;d/=10){
      for(int i=0;i<1000;i++){
	int dx=0;
	for(int j=0;j<n;j++){
	  if(dsq(cx,cy,cz,x[dx],y[dx],z[dx])<dsq(cx,cy,cz,x[j],y[j],z[j])){
	    dx=j;
	  }
	}
	double bx,by,bz;
	bx=x[dx]-cx;
	by=y[dx]-cy;
	bz=z[dx]-cz;
	f=sqrt(S(bx)+S(by)+S(bz));
	cx+=bx*d/f;
	cy+=by*d/f;
	cz+=bz*d/f;
      }
    }
    cout.precision(5);
    cout<<fixed<<f<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3220
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define Fi first
#define Se second
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define szz(x) (int)(x).size()
#define rep(i, n) for(int i=0;i<(n);i++)
typedef tuple<int, int, int> t3;

using T = double;
int n;
T x[110], y[110], z[110];
T sq(T x) { return x * x; }
T ssq(T a, T b, T c) { return sq(a) + sq(b) + sq(c); }

pair<int, T> far(T px, T py, T pz) {
	int r = -1;
	T f = -1;
	for (int i = 1; i <= n; i++) {
		T dis = ssq(px - x[i], py - y[i], pz - z[i]);
		if (f < dis) f = dis, r = i;
	}
	return { r, f };
}

int main() {
	while (scanf("%d", &n) == 1 && n) {
		for (int i = 1; i <= n; i++) scanf("%lf%lf%lf", x + i, y + i, z + i);
		auto g = [](T l, T r) {
			return l + (r - l) * (T)0.5;
		};
		T ans = 1e9;
		rep(a, 1) {
			T px = g(*min_element(x + 1, x + 1 + n), *max_element(x + 1, x + 1 + n));
			T py = g(*min_element(y + 1, y + 1 + n), *max_element(y + 1, y + 1 + n));
			T pz = g(*min_element(z + 1, z + 1 + n), *max_element(z + 1, z + 1 + n));
			T d = far(px, py, pz).Se * 0.1;
			rep(t, 100000) {
				int i; T r;
				tie(i, r) = far(px, py, pz);
				T vx = x[i] - px, vy = y[i] - py, vz = z[i] - pz;
				T lp = d / sqrt(r);
				px += vx * lp; py += vy * lp; pz += vz * lp;
				d = d * 0.9995;
			}
			ans = min(ans, sqrt(far(px, py, pz).Se));
		}
		printf("%.5lf\n", ans);
	}
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3180
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define Fi first
#define Se second
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define szz(x) (int)(x).size()
#define rep(i, n) for(int i=0;i<(n);i++)
typedef tuple<int, int, int> t3;

using T = long double;
int n;
T x[110], y[110], z[110];
T sq(T x) { return x * x; }
T ssq(T a, T b, T c) { return sq(a) + sq(b) + sq(c); }

pair<int, T> far(T px, T py, T pz) {
	int r = -1;
	T f = -1;
	for (int i = 1; i <= n; i++) {
		T dis = ssq(px - x[i], py - y[i], pz - z[i]);
		if (f < dis) f = dis, r = i;
	}
	return { r, f };
}

int main() {
	while (scanf("%d", &n) == 1 && n) {
		for (int i = 1; i <= n; i++) scanf("%Lf%Lf%Lf", x + i, y + i, z + i);
		auto g = [](T l, T r) {
			return l + (r - l) * (T)0.5;
		};
		T ans = 1e9;
		rep(a, 1) {
			T px = g(*min_element(x + 1, x + 1 + n), *max_element(x + 1, x + 1 + n));
			T py = g(*min_element(y + 1, y + 1 + n), *max_element(y + 1, y + 1 + n));
			T pz = g(*min_element(z + 1, z + 1 + n), *max_element(z + 1, z + 1 + n));
			T d = far(px, py, pz).Se * 0.1;
			rep(t, 100000) {
				int i; T r;
				tie(i, r) = far(px, py, pz);
				T vx = x[i] - px, vy = y[i] - py, vz = z[i] - pz;
				T lp = d / sqrt(r);
				px += vx * lp; py += vy * lp; pz += vz * lp;
				d = d * 0.9995;
			}
			ans = min(ans, sqrt(far(px, py, pz).Se));
		}
		printf("%.5Lf\n", ans);
	}
	return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 3156
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define Fi first
#define Se second
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define szz(x) (int)(x).size()
#define rep(i, n) for(int i=0;i<(n);i++)
typedef tuple<int, int, int> t3;

using T = long double;
int n;
T x[110], y[110], z[110];
T sq(T x) { return x * x; }
T ssq(T a, T b, T c) { return sq(a) + sq(b) + sq(c); }

pair<int, T> far(T px, T py, T pz) {
	int r = -1;
	T f = -1;
	for (int i = 1; i <= n; i++) {
		T dis = ssq(px - x[i], py - y[i], pz - z[i]);
		if (f < dis) f = dis, r = i;
	}
	return { r, f };
}

int main() {
	while (scanf("%d", &n) == 1 && n) {
		for (int i = 1; i <= n; i++) scanf("%Lf%Lf%Lf", x + i, y + i, z + i);
		auto g = [](T l, T r) {
			return l + (r - l) * ((T)rand() / RAND_MAX);
		};
		T ans = 1e9;
		rep(a, 2) {
			T px = g(*min_element(x + 1, x + 1 + n), *max_element(x + 1, x + 1 + n));
			T py = g(*min_element(y + 1, y + 1 + n), *max_element(y + 1, y + 1 + n));
			T pz = g(*min_element(z + 1, z + 1 + n), *max_element(z + 1, z + 1 + n));
			T d = far(px, py, pz).Se * 0.1;
			rep(t, 100000) {
				int i; T r;
				tie(i, r) = far(px, py, pz);
				T vx = x[i] - px, vy = y[i] - py, vz = z[i] - pz;
				T lp = d / sqrt(r);
				px += vx * lp; py += vy * lp; pz += vz * lp;
				d = d * 0.9995;
			}
			ans = min(ans, sqrt(far(px, py, pz).Se));
		}
		printf("%.5Lf\n", ans);
	}
	return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 3152
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define Fi first
#define Se second
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define szz(x) (int)(x).size()
#define rep(i, n) for(int i=0;i<(n);i++)
typedef tuple<int, int, int> t3;

using T = long double;
int n;
T x[110], y[110], z[110];
T sq(T x) { return x * x; }
T ssq(T a, T b, T c) { return sq(a) + sq(b) + sq(c); }

pair<int, T> far(T px, T py, T pz) {
	int r = -1;
	T f = -1;
	for (int i = 1; i <= n; i++) {
		T dis = ssq(px - x[i], py - y[i], pz - z[i]);
		if (f < dis) f = dis, r = i;
	}
	return { r, f };
}

int main() {
	while (scanf("%d", &n) == 1 && n) {
		for (int i = 1; i <= n; i++) scanf("%Lf%Lf%Lf", x + i, y + i, z + i);
		auto g = [](T l, T r) {
			return l + (r - l) * ((T)rand() / RAND_MAX);
		};
		T ans = 1e9;
		rep(a, 10) {
			T px = g(*min_element(x + 1, x + 1 + n), *max_element(x + 1, x + 1 + n));
			T py = g(*min_element(y + 1, y + 1 + n), *max_element(y + 1, y + 1 + n));
			T pz = g(*min_element(z + 1, z + 1 + n), *max_element(z + 1, z + 1 + n));
			T d = far(px, py, pz).Se * 0.1;
			rep(t, 100000) {
				int i; T r;
				tie(i, r) = far(px, py, pz);
				T vx = x[i] - px, vy = y[i] - py, vz = z[i] - pz;
				T lp = d / sqrt(r);
				px += vx * lp; py += vy * lp; pz += vz * lp;
				d = d * 0.9995;
			}
			ans = min(ans, sqrt(far(px, py, pz).Se));
		}
		printf("%.5Lf\n", ans);
	}
	return 0;
}
accuracy: 1
time_ms: 1130
memory_kb: 3236
final_rank: 15

code_snippet: #include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
const double EPS = 1e-6;
const double INF = 1e12;
 
struct Point{
    double x,y,z;
    Point(double x, double y, double z):x(x), y(y), z(z){}
    Point(){}
    Point &operator +=(const Point &a){ x+=a.x; y+=a.y; z+=a.z; return *this; }
    Point &operator -=(const Point &a){ x-=a.x; y-=a.y; z-=a.z; return *this; }
    Point &operator *=(const double &a){ x*=a; y*=a; z*=a; return *this; }
    Point operator +(const Point &a) const{ return Point(x+a.x, y+a.y, z+a.z); }
    Point operator -(const Point &a) const{ return Point(x-a.x, y-a.y, z-a.z); }
    Point operator *(const double &a) const{ return Point(a*x, a*y, a*z); }
    Point operator -() { return Point(-x, -y, -z); }
};
 
double dot(const Point &a, const Point &b){
    return a.x*b.x +a.y*b.y +a.z*b.z;
}
Point cross(const Point &a, const Point &b){
    return Point(a.y*b.z -a.z*b.y, a.z*b.x -a.x*b.z, a.x*b.y -a.y*b.x);
}
double abs(const Point &a){
    return sqrt(dot(a, a));
}
Point unit(const Point &a){
    return a *(1/abs(a));
}
bool operator ==(const Point &a, const Point &b){
    return abs(a-b) < EPS;
}

vector<double> solve_linear_equation(vector<vector<double> > a){
    int n = a.size();
    for(int i=0; i<n; i++){
        for(int j=i+1; j<n; j++){
            if(abs(a[j][i]) > abs(a[i][i])){
                swap(a[i], a[j]);
            }
        }
        for(int j=n; j>=i; j--){
            a[i][j] /= a[i][i];
        }
        for(int j=i+1; j<n; j++){
            for(int k=n; k>=i; k--){ 
                a[j][k] -= a[i][k]*a[j][i];
            }
        }
    }
    vector<double> res(n);
    for(int i=n-1; i>=0; i--){
        res[i] = a[i][n];
        for(int j=n-1; j>i; j--){
            res[i] -= a[i][j]*res[j];
        }
    }
    return res;
}

int main(){
    while(1){
        int n;
        cin >> n;
        if(n==0) break;

        vector<Point> p(n);
        for(int i=0; i<n; i++){
            cin >> p[i].x >> p[i].y >> p[i].z;
        }

        vector<Point> cand;
        vector<double> r;
        Point c[4];
        for(int i=0; i<n; i++){
            c[0] = p[i];
            for(int j=i+1; j<n; j++){
                c[1] = p[j];
                for(int k=j+1; k<n; k++){
                    c[2] = p[k];
                    for(int l=k+1; l<n; l++){
                        c[3] = p[l];
                        //4点(連立方程式)
                        vector<vector<double> > mat(3, vector<double>(4));
                        for(int s=0; s<3; s++){
                            mat[s][0] = 2*(c[s].x -c[s+1].x);
                            mat[s][1] = 2*(c[s].y -c[s+1].y);
                            mat[s][2] = 2*(c[s].z -c[s+1].z);
                            mat[s][3] = (c[s].x *c[s].x -c[s+1].x *c[s+1].x)
                                +(c[s].y *c[s].y -c[s+1].y *c[s+1].y)
                                +(c[s].z *c[s].z -c[s+1].z *c[s+1].z);
                        }
                        vector<double> ret = solve_linear_equation(mat);
                        double x = c[0].x -ret[0];
                        double y = c[0].y -ret[1];
                        double z = c[0].z -ret[2];
                        cand.push_back(Point(ret[0], ret[1], ret[2]));
                        r.push_back(sqrt(x*x +y*y +z*z));
                    }
                    //3点(外心のベクトル表示)
                    double sin2[3];
                    for(int i=0; i<3; i++){
                        double A = abs(c[(i+1)%3] -c[(i+2)%3]);
                        double B = abs(c[i] -c[(i+1)%3]);
                        double C = abs(c[i] -c[(i+2)%3]);
                        double cosa = (B*B +C*C -A*A)/(2*B*C);
                        sin2[i] = sin(2*acos(cosa));
                    }
                    Point center = (c[0]*sin2[0] +c[1]*sin2[1] +c[2]*sin2[2])
                        *(1/(sin2[0] +sin2[1] +sin2[2]));
                    cand.push_back(center);
                    r.push_back(abs(center -c[0]));
                }
                //2点(直径)
                cand.push_back((c[0]+c[1]) *0.5);
                r.push_back(abs(c[0]-c[1])/2);
            }
        }

        double ans = INF;
        for(int i=0; i<(int)cand.size(); i++){
            bool ok = true;
            for(int j=0; j<n; j++){
                if(abs(p[j] -cand[i]) > r[i] +EPS){
                    ok = false;
                    break;
                }
            }
            if(ok){
                ans = min(ans, r[i]);
            }
        }
        
        cout << fixed << setprecision(5);
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 5028
final_rank: 16

code_snippet: #include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<ctime>
#include <algorithm>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-8;
int n;
/*
机选取一个点作为初始解，然后不断向当前距离最远点靠近，这是一个不断调整的过程，
将对应模拟淬火算法中不断向内能最低（半径最小）这一目标函数逼近，温度对应控制变量。
*/
struct Point
{
	double x,y,z;
	Point(double x = 0, double y = 0, double z = 0)
	{
		x = x;
		y = y;
		z = z;	
	}
}p[1010];
double dis(Point a, Point 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) );
}

void solve()
{
	/*
	不要用随机取点，取不到结果
	*/
	Point temp = p[1];
	double ans = 9999999;
	double T = 100.0;
	while( T > eps)//如果温度小于eps，则达到最优解
	{
		int k = 1;
		for (int i = 1; i <= n; i++)
		{
			if (dis(temp, p[i]) > dis(temp, p[k]))
				k = i;//寻找距离temp最远的点
		}
		double dista = dis(temp, p[k]);
		ans = min(ans, dista);//找出该点的最小距离

			temp.x += (p[k].x - temp.x) / dista * T;
			//离temp最远的点与temp的x坐标差/两点最小距离*温度
			temp.y += (p[k].y - temp.y) / dista * T;
			temp.z += (p[k].z - temp.z) / dista * T;
		T *= 0.988;//降火的幅度
	}
	printf("%.5f\n", ans);
}

int main()
{
	std::ios::sync_with_stdio(false);
	while (cin>> n)
	{
		
		if (n == 0)break;
		memset(p, 0, sizeof(p));
		for (int i = 1; i <= n; i++)
		{
			cin >> p[i].x >> p[i].y>>p[i].z;
		}
		solve();
	}
}
accuracy: 1
time_ms: 10
memory_kb: 3244
final_rank: 7

code_snippet: //  Super Star Aizu - 1231 
//  status:
//  time:
//  main.cpp
//  Created by livin2 on 18/04/20.
//  Copyright © 2017年 livin2. All rights reserved.
//  Note:#
//#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <iomanip>
//#include <map>
//#include <fstream>
using namespace std;
const int precision = 100000;
const double DZERO = 1e-9;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
struct pos
{
	double x, y,z;
	pos() {}
	pos(double x,double y,double z):x(x),y(y),z(z){}
	void moveRand(double step);
};
double len(const pos &a,const pos &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 Rand()
{
	return (double)(rand() % precision) / precision;
}

struct SuperStar
{
	int n;
	//double X, Y;
	double maxX = 100.0;
	double Dstep, ans;
	pos ansp;
	static const int pRandNum = 40;
	static const int stepRandNum = 20;
	const double minDstep = 1e-6;
	const double ratio = 0.98;
	vector<pos> P;
	vector<double> Rs;
	vector<pos> ansPs;
	SuperStar(int n);
	pos posRand();
	double getRadius(const pos &p);
	bool isInRange(const pos &p);
	void solve();
};
int main()
{
	double x, y;int n;
	while (cin>>n&&n)
	{
		SuperStar exp(n);
		exp.solve();
		cout <<fixed<<setprecision(5)
			<<exp. ans << endl;
	}
	return 0;
}

SuperStar::SuperStar(int n):n(n),Rs(pRandNum), ansPs(pRandNum)
{
	double xx, yy,zz;
	for (int i = 0; i < n; i++)
	{
		cin >> xx >> yy>>zz;
		P.push_back(pos(xx,yy,zz));
	}
	Dstep = sqrt(2) * maxX / sqrt(n);//sqrt (2) *...
}
void pos::moveRand(double step)
{
	double ang = Rand() * 2 * PI;
	z += step * sin(ang);
	double xy = step * cos(ang);
	ang = Rand() * 2 * PI;
	x += xy * cos(ang);
	y += xy * sin(ang);
	
}
pos SuperStar::posRand()
{
	double x = maxX * Rand();
	double y = maxX * Rand();
	double z = maxX * Rand();
	return pos(x,y,z);
}

double SuperStar::getRadius(const pos &p)
{
	double res = 0;
	for (int i = 0; i < P.size(); i++)
		res = max(res,len(P[i],p));
	return res;
}

bool SuperStar::isInRange(const pos & p)
{
	if (p.x > DZERO&&p.x - maxX <= DZERO && p.y > DZERO&&p.y - maxX <= DZERO && p.z > DZERO&&p.z - maxX <= DZERO)
		return true;
	return false;
}



void SuperStar::solve()
{
	//init
	for (int i = 0; i < pRandNum; i++)
	{
		ansPs[i] = posRand();
		Rs[i] = getRadius(ansPs[i]);
	}
	//SA
	while (Dstep>minDstep)
	{
		for (int i = 0; i < pRandNum; i++)
		{
			pos cur = ansPs[i];
			for (int j = 0; j < stepRandNum; j++)
			{
				cur.moveRand(Dstep);
				if (isInRange(cur))
				{
					double rad = getRadius(cur);
					if (rad < Rs[i])
					{
						Rs[i] = rad;
						ansPs[i].x = cur.x;
						ansPs[i].y = cur.y;
						ansPs[i].z = cur.z;
					}
				}
			}
		}
		Dstep *= ratio;
	}
	//
	ans = INF;
	ansp = ansPs[0];
	for (int i = 0; i < pRandNum; i++)
	{
		if (Rs[i] < ans)
		{
			ans = Rs[i];
			ansp = ansPs[i];
		}
	}
}
accuracy: 1
time_ms: 2650
memory_kb: 3544
final_rank: 18

code_snippet: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const double EPS = 1e-15;
const double eps = 1e-15;
const int num = 15;
const double PI = acos(-1.0);
const double INF = 0x3f3f3f3f;

double T = 100;
double r = 0.99;

struct Point{
    double x,y,z;
};

double dist(Point A,Point 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));
}

Point p[num],m[num];
int n;
double d[num];
double ans;

double MAX(Point t)
{
    double res=0;
    for(int i=0;i<n;i++)
        res=max(res,dist(t,p[i]));
    ans=min(ans,res);
    return res;
}

int main()
{
    srand(time(0));
    while(cin>>n)
    {
        if(n==0)
            break;
        for(int i=0;i<n;i++)
            cin>>p[i].x>>p[i].y>>p[i].z;
        double t=T;
        Point now,next;
        now.x=now.y=now.z=0;
        int pos;
        ans=1e100;
        while(t>EPS)
        {
            double dis=0;
            for(int i=0;i<n;i++)
            {
                if(dis<dist(now,p[i]))
                {
                    pos=i;
                    dis=dist(now,p[i]);
                }
            }
            next.x=now.x+(p[pos].x-now.x)/dis*t;
            next.y=now.y+(p[pos].y-now.y)/dis*t;
            next.z=now.z+(p[pos].z-now.z)/dis*t;
            double x=MAX(now)-MAX(next);
            if(x>0||exp(x/t)>(rand()%1000+1)/1000.0)
                now=next;
            t*=r;
        }
        printf("%.5f\n",ans);
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3744
final_rank: 14

code_snippet: #include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
    x=0;char ch;bool flag = false;
    while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
    while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
const int maxn = 45;
const double eps = 1e-15;
const double det = 0.99;
struct Point{
    double x,y,z;
    Point(const double &a=0,const double &b=0,const double &c=0){
        x=a;y=b;z=c;
    }
};
inline double dis(const Point &a,const Point &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));
}
int n;double ans = 1e100;
Point p[maxn];
inline double f(const Point &x){
    double ret = 0;
    for(int i=1;i<=n;++i) ret = max(ret,dis(x,p[i]));
    if(ret < ans) ans = ret;
    return ret;
}
inline double ran(){
    return (rand() % 1000 + 1)/1000.0;
}
Point nw;
int main(){
    srand(2333);
    while(1){
        read(n);if(n == 0) break;
        nw.x = nw.y = nw.z = 0;
        ans = 1e100;
        for(int i=1;i<=n;++i){
            scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z);
        }
        double T = 100.0,x;
        double dist;int pos;
        while(T > eps){
            dist = 0.0;
            for(int i=1;i<=n;++i){
                if(dist < dis(nw,p[i])){
                    pos = i;dist = dis(nw,p[i]);
                }
            }
            Point nx(
                nw.x+(p[pos].x-nw.x)/dist*T,
                nw.y+(p[pos].y-nw.y)/dist*T,
                nw.z+(p[pos].z-nw.z)/dist*T
                );
            x = f(nw) - f(nx);
            if(x > 0 || exp(x/T) > ran()) nw = nx;
            T *= det;
        }
        printf("%.5lf\n",ans);
    }
    getchar();getchar();
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3120
final_rank: 4

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Point{
	double x,y,z;
};

int N;
Point point[30];

double calc_len(Point a,Point 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));
}

void func(){
	for(int i = 0; i < N; i++){
		scanf("%lf %lf %lf",&point[i].x,&point[i].y,&point[i].z);
	}

	Point tmp;
	tmp.x = 50.0,tmp.y = 50.0,tmp.z = 50.0;
	double ans = 10000.0,max_dist,move_dist = 10.0;
	int max_index;

	for(int i = 0; i < 10000; i++){
		max_dist = -1;

		for(int k = 0; k < N; k++){
			if(max_dist < calc_len(tmp,point[k])){
				max_dist = calc_len(tmp,point[k]);
				max_index = k;
			}
		}

		if(ans > max_dist){
			ans = max_dist;
		}

		tmp.x += (point[max_index].x-tmp.x)*move_dist;
		tmp.y += (point[max_index].y-tmp.y)*move_dist;
		tmp.z += (point[max_index].z-tmp.z)*move_dist;

		if(i%100 == 0)move_dist /= 2;
	}
	printf("%.10lf\n",ans);
}


int main(){
	while(true){
		scanf("%d",&N);
		if(N == 0)break;

		func();
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3184
final_rank: 5

code_snippet: #include <string>
#include <iomanip>
#include <iostream>
#include <algorithm>
using namespace std;
int n; double x[35], y[35], z[35];
double solve(double px, double py, double pz) {
	double ret = 0.0;
	for (int i = 0; i < n; i++) ret = max(ret, (x[i] - px) * (x[i] - px) + (y[i] - py) * (y[i] - py) + (z[i] - pz) * (z[i] - pz));
	return sqrt(ret);
}
double solve1(double px, double py) {
	double l = -1.0e+3, r = 1.0e+3;
	for (int i = 0; i < 70; i++) {
		double m1 = (l * 2.0 + r) / 3.0;
		double m2 = (l + r * 2.0) / 3.0;
		if (solve(px, py, m1) < solve(px, py, m2)) r = m2;
		else l = m1;
	}
	return solve(px, py, l);
}
double solve2(double px) {
	double l = -1.0e+3, r = 1.0e+3;
	for (int i = 0; i < 70; i++) {
		double m1 = (l * 2.0 + r) / 3.0;
		double m2 = (l + r * 2.0) / 3.0;
		if (solve1(px, m1) < solve1(px, m2)) r = m2;
		else l = m1;
	}
	return solve1(px, l);
}
double solve3() {
	double l = -1.0e+3, r = 1.0e+3;
	for (int i = 0; i < 70; i++) {
		double m1 = (l * 2.0 + r) / 3.0;
		double m2 = (l + r * 2.0) / 3.0;
		if (solve2(m1) < solve2(m2)) r = m2;
		else l = m1;
	}
	return solve2(l);
}
int main() {
	while (cin >> n, n) {
		for (int i = 0; i < n; i++) cin >> x[i] >> y[i] >> z[i];
		double ret = solve3();
		cout << fixed << setprecision(10) << ret << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 1720
memory_kb: 3268
final_rank: 17

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int n; long double x[30], y[30], z[30];
long double norm(long double ax, long double ay, long double az) {
	long double maxn = 0;
	for (int i = 0; i < n; i++) {
		maxn = max(maxn, (ax - x[i])*(ax - x[i]) + (ay - y[i])*(ay - y[i]) + (az - z[i])*(az - z[i]));
	}
	return maxn;
}
long double solve(int depth, long double L1, long double L2) {
	long double L = -114.514l, R = 100.0l, c1, c2, maxn = 1e9;
	for (int i = 0; i < 70; i++) {
		c1 = (L + L + R) / 3.0l;
		c2 = (L + R + R) / 3.0l;
		long double I1, I2;
		if (depth == 0) { I1 = solve(depth + 1, c1, L2); I2 = solve(depth + 1, c2, L2); }
		if (depth == 1) { I1 = solve(depth + 1, L1, c1); I2 = solve(depth + 1, L1, c2); }
		if (depth == 2) { I1 = norm(L1, L2, c1); I2 = norm(L1, L2, c2); }
		if (I1 < I2)R = c2; else L = c1;
		maxn = min(maxn, min(I1, I2));
	}
	return maxn;
}
int main() {
	while (true) {
		cin >> n; if (n == 0)break; for (int i = 0; i < n; i++)cin >> x[i] >> y[i] >> z[i];
		printf("%.12Lf\n", sqrtl(solve(0, 0, 0)));
	}
	return 0;
}
accuracy: 1
time_ms: 3180
memory_kb: 3136
final_rank: 19

code_snippet: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

#define MAX_N	(30)
#define MAX_CAN	(10000)

#define DELTA	((double)1e-6)

/* typedef */

typedef vector<int> vi;
typedef vector<long long> vl;
typedef vector<double> vd;
typedef pair<int,int> pii;
typedef pair<long,long> pll;
typedef long long ll;

struct can_t {
  double r, x, y, z;
};

struct pt_t {
  double x, y, z;
};

/* classes */

class LessCan {
public:
  bool operator()(const can_t& lc, const can_t& rc) const {
    return lc.r < rc.r;
  }
};

/* global variables */

static pt_t signs[] = {
  { 1, 1, 1}, { 1, 1, -1}, { 1, -1, 1}, { 1, -1, -1},
  {-1, 1, 1}, {-1, 1, -1}, {-1, -1, 1}, {-1, -1, -1}
};

static int n;
static pt_t pts[MAX_N];

static can_t candidate[MAX_CAN], new_candidate[MAX_CAN];

/* subroutines */

double max_r(double x, double y, double z) {
  double max_r2 = 0.0;

  for (int i = 0; i < n; i++) {
    pt_t& p = pts[i];
    double dx = x - p.x;
    double dy = y - p.y;
    double dz = z - p.z;
    double r2 = dx * dx + dy * dy + dz * dz;
    if (max_r2 < r2) max_r2 = r2;
  }

  return sqrt(max_r2);
}

double solve_by_partition() {
  candidate[0].x = 50.0;
  candidate[0].y = 50.0;
  candidate[0].z = 50.0;

  int count = 1;
  double size = 100.0;
  double min_sofar = 1e50;
  double root3 = sqrt(3.0);

  while (size > DELTA) {
    size /= 2;
    int k = 0;

    for (int i = 0; i < count; i++) {
      for (int d = 0; d < 8; d++) {
        can_t c = candidate[i];
        double sizeh = size / 2;
        c.x += signs[d].x * sizeh;
        c.y += signs[d].y * sizeh;
        c.z += signs[d].z * sizeh;
        c.r = max_r(c.x, c.y, c.z);
        if (min_sofar > c.r) min_sofar = c.r;
        if (c.r > min_sofar + sizeh * root3) continue;
        if (k >= MAX_CAN) break;

        new_candidate[k] = c;
        k++;
      }
      if (k >= MAX_CAN) break;
    }

    count = k;
    for (int i = 0; i < count; i++)
      candidate[i] = new_candidate[i];

    sort(candidate, candidate + count, LessCan());
  }

  return min_sofar;
}

/* main */

int main() {
  for (;;) {
    cin >> n;
    if (n == 0) break;

    for (int i = 0; i < n; i++) {
      cin >> pts[i].x >> pts[i].y >> pts[i].z;
    }

    printf("%.5lf\n", solve_by_partition());
  }
  
  return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 1888
final_rank: 3

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define MAX 30
#define EPS 1e-9

class Point{
public:
  double x,y,z;
  Point(){}
  Point(double x,double y,double z) : x(x),y(y),z(z) {}
};

double getDistance(const Point &a,const Point &b){
  return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2)+pow(a.z-b.z,2));
}

istream &operator >> (istream &is,Point &p){
  is >> p.x >> p.y >> p.z;
  return is;
}

int main(){
  int N;
  Point point[MAX];
  while(cin >> N, N){
    double x = 0, y = 0, z = 0;
    for(int i = 0 ; i < N ; i++){
      cin >> point[i];
      x += point[i].x;
      y += point[i].y;
      z += point[i].z;
    }
    x /= N; y /= N; z /= N;
    int pos = -1;
    double d = 0.8, ans = 0;
    Point p(x,y,z);
    while(d > EPS){
      for(int i = 0 ; i < 150 ; i++){
        ans = 0;
        for(int j = 0 ; j < N ; j++){
          double dist = getDistance(p,point[j]);
          if(ans < dist){
            ans = dist;
            pos = j;
          }
        }
        p.x += (point[pos].x-p.x)*d;
        p.y += (point[pos].y-p.y)*d;
        p.z += (point[pos].z-p.z)*d;
      }
      d /= 2;
    }
    printf("%.6f\n",ans);
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1248
final_rank: 2

code_snippet: #include<stdio.h>
#include<algorithm>
#include<math.h>
using namespace std;
double x[32];
double y[32];
double z[32];
int main(){
	int a;
	while(scanf("%d",&a),a){
		for(int i=0;i<a;i++)scanf("%lf%lf%lf",x+i,y+i,z+i);
		double nx=50;
		double ny=50;
		double nz=50;
		double res=9999999;
		double mv=10;
		for(int i=0;i<10000;i++){
			double r=0;
			int at=0;
			for(int j=0;j<a;j++){
				if(r<sqrt((x[j]-nx)*(x[j]-nx)+(y[j]-ny)*(y[j]-ny)+(z[j]-nz)*(z[j]-nz))){
					at=j;
					r=sqrt((x[j]-nx)*(x[j]-nx)+(y[j]-ny)*(y[j]-ny)+(z[j]-nz)*(z[j]-nz));
				}
			}
			if(r<res){
				res=r;
			}
			nx+=(x[at]-nx)*mv;
			ny+=(y[at]-ny)*mv;
			nz+=(z[at]-nz)*mv;
			
			if(i%100==0)mv/=2;
		}
		printf("%.5f\n",res);
	}
}
accuracy: 1
time_ms: 30
memory_kb: 1096
final_rank: 1