Problem:
Minimum Enclosing Circle
There are $N$ points on a two-dimensional plane. Find the smallest circle that encloses all of these points.
Such a circle is called the Minimum Enclosing Circle. A Minimum Enclosing Circle can be efficiently found using an algorithm based on the following properties.
Let the sequence of $N$ points be $p_0, p_1, ..., p_{N-1}$, and let $P_i = \{p_0, p_1, ..., p_i\}$.
Let $D_i$ be the minimum enclosing circle of $P_i$.
For $1 < i < N$, the following holds:
If $p_i$ is contained in $D_{i-1}$, then $D_i = D_{i-1}$.
If $p_i$ is not contained in $D_{i-1}$, then $p_i$ lies on the boundary of $D_i$.
Input
The input is given in the following format.
$N$
$x_0$ $y_0$
$x_1$ $y_1$
:
$x_{N-1}$ $y_{N-1}$
The first line contains the number of points $N$. For the next $N$ lines, the coordinates of the $i$-th point are given as two integers $x_i$ and $y_i$.
Output
Output the smallest circle in the following format.
$cx$ $cy$ $r$
Output the center coordinates $(cx, cy)$ of the circle and its radius $r$ on a single line, separated by spaces. The output values should be in a decimal fraction with an error less than 0.000001.
Constraints
$2 \leq N \leq 100000$
$-1000000 \leq x_i, y_i \leq 1000000$
No two given points have the same coordinates.
Sample Input and Output
Sample Input 1
5
0 0
0 3
4 0
3 2
2 4
Sample Output 1
2.00000000 1.50000000 2.50000000
Sample Input 2
3
0 0
1 1
2 2
Sample Output 2
1.00000000 1.00000000 1.41421356

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vi vector<int>
#define vl vector<ll>
#define ov4(a, b, c, d, name, ...) name
#define rep3(i, a, b, c) for(ll i = (a); i < (b); i += (c))
#define rep2(i, a, b) rep3(i, a, b, 1)
#define rep1(i, n) rep2(i, 0, n)
#define rep0(n) rep1(aaaaa, n)
#define rep(...) ov4(__VA_ARGS__, rep3, rep2, rep1, rep0)(__VA_ARGS__)
#define per(i, a, b) for(ll i = (a)-1; i >= (b); i--)
#define fore(e, v) for(auto&& e : v)
#define all(a) begin(a), end(a)
#define si(a) (int)(size(a))
#define lb(v, x) (lower_bound(all(v), x) - begin(v))
#define eb emplace_back

template<typename T, typename S> bool chmin(T& a, const S& b) { return a > b ? a = b, 1 : 0; }
template<typename T, typename S> bool chmax(T& a, const S& b) { return a < b ? a = b, 1 : 0; }

const int INF = 1e9 + 100;
const ll INFL = 3e18 + 100;

#define i128 __int128_t

struct _ {
   _() { cin.tie(0)->sync_with_stdio(0), cout.tie(0); }
} __;

template<class T> int sgn(T x) { return (x > 0) - (x < 0); }
template<class T>
struct Point {
    typedef Point P;
    T x, y;
    explicit Point(T x=0, T y=0) : x(x), y(y) {}
    bool operator<(P p) const { return tie(x, y) < tie(p.x, p.y); }
    bool operator==(P p) const { return tie(x, y) == tie(p.x, p.y); }
    P operator+(P p) const { return P(x + p.x, y + p.y); }
    P operator-(P p) const { return P(x - p.x, y - p.y); }
    P operator*(T d) const { return P(x * d, y * d); }
    P operator/(T d) const { return P(x / d, y / d); }
    T dot(P p) const { return x * p.x + y * p.y; }
    T cross(P p) const { return x * p.y - y * p.x; }
    T cross(P a, P b) const { return (a - *this).cross(b - *this); }
    T dist2() const { return x*x + y*y; }
    double dist() const { return sqrt((double)dist2()); }
    P perp() const { return P(-y, x); }
};

typedef Point<double> P;
double ccRadius(const P& A, const P& B, const P& C) {
    return (B - A).dist() * (C - B).dist() * (A - C).dist() / abs((B - A).cross(C - A)) / 2;
}

P ccCenter(const P& A, const P& B, const P& C) {
    P b = C - A, c = B - A;
    return A + (b * c.dist2() - c * b.dist2()).perp() / b.cross(c) / 2;
}

pair<P, double> mec(vector<P> ps) {
    shuffle(all(ps), mt19937(time(0)));
    P o = ps[0];
    double r = 0, EPS = 1 + 1e-8;
    rep(i, si(ps)) if ((o - ps[i]).dist() > r * EPS) {
        o = ps[i], r = 0;
        rep(j, i) if ((o - ps[j]).dist() > r * EPS) {
            o = (ps[i] + ps[j]) / 2;
            r = (o - ps[i]).dist();
            rep(k, j) if ((o - ps[k]).dist() > r * EPS) {
                o = ccCenter(ps[i], ps[j], ps[k]);
                r = (o - ps[i]).dist();
            }
        }
    }
    return {o, r};
}

int main() {
    int n;
    cin >> n;
    vector<P> v;
    rep(i, n) {
        double x, y;
        cin >> x >> y;
        v.push_back(P(x, y));
    }

    cout << setprecision(20) << fixed;
    auto res = mec(v);
    cout << res.first.x << " " << res.first.y << " " << res.second << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 7404
final_rank: 4

code_snippet: // https://tubo28.me/compprog/algorithm/ より.

#include <bits/stdc++.h>
// #define int int64_t

#define FOR(i, a, b) for (int i = (a); i < int(b); ++i)
#define RFOR(i, a, b) for (int i = (b)-1; i >= int(a); --i)
#define rep(i, n) FOR(i, 0, n)
#define rep1(i, n) FOR(i, 1, int(n) + 1)
#define rrep(i, n) RFOR(i, 0, n)
#define rrep1(i, n) RFOR(i, 1, int(n) + 1)
#define all(c) begin(c), end(c)
namespace io {
#ifdef LOCAL
#define dump(...)                                         \
    do {                                                  \
        std::ostringstream os;                            \
        os << __LINE__ << ":\t" << #__VA_ARGS__ << " = "; \
        io::print_to(os, ", ", "\n", __VA_ARGS__);        \
        std::cerr << io::highlight(os.str());             \
    } while (0)
#define dump_(cntnr)                                 \
    do {                                             \
        std::ostringstream os;                       \
        os << __LINE__ << ":\t" << #cntnr << " = ["; \
        io::print_to_(os, ", ", "]\n", all(cntnr));  \
        std::cerr << io::highlight(os.str());        \
    } while (0)
#define dumpf(fmt, ...)                             \
    do {                                            \
        const int N = 4096;                         \
        auto b = new char[N];                       \
        int l = snprintf(b, N, "%d:\t", __LINE__);  \
        snprintf(b + l, N - l, fmt, ##__VA_ARGS__); \
        std::cerr << io::highlight(b) << std::endl; \
        delete[] b;                                 \
    } while (0)
#else
#define dump(...)
#define dump_(...)
#define dumpf(...)
#endif
std::string highlight(std::string s) {
#ifdef _MSC_VER
    return s;
#else
    return "\033[33m" + s + "\033[0m";
#endif
}
template <typename T>
void print_to(std::ostream &os, std::string, std::string tail, const T &first) {
    os << first << tail;
}
template <typename F, typename... R>
void print_to(std::ostream &os, std::string del, std::string tail, const F &first,
              const R &... rest) {
    os << first << del;
    print_to(os, del, tail, rest...);
}
template <typename I>
void print_to_(std::ostream &os, std::string del, std::string tail, I begin, I end) {
    for (I it = begin; it != end;) {
        os << *it;
        os << (++it != end ? del : tail);
    }
}
template <typename F, typename... R>
void println(const F &first, const R &... rest) {
    print_to(std::cout, "\n", "\n", first, rest...);
}
template <typename F, typename... R>
void print(const F &first, const R &... rest) {
    print_to(std::cout, " ", "\n", first, rest...);
}
template <typename I>
void println_(I begin, I end) {
    print_to_(std::cout, "\n", "\n", begin, end);
}
template <typename I>
void print_(I begin, I end) {
    print_to_(std::cout, " ", "\n", begin, end);
}
template <typename C>
void println_(const C &cntnr) {
    println_(std::begin(cntnr), std::end(cntnr));
}
template <typename C>
void print_(const C &cntnr) {
    print_(std::begin(cntnr), std::end(cntnr));
}
int _ = (
#ifndef LOCAL
    std::cin.tie(nullptr), std::ios::sync_with_stdio(false),
#endif
    std::cout.precision(10), std::cout.setf(std::ios::fixed));
}
using io::print;
using io::println;
using io::println_;
using io::print_;
template <typename T>
using vec = std::vector<T>;
using vi = vec<int>;
using vvi = vec<vi>;
using pii = std::pair<int, int>;
using ll = long long;
using ld = long double;
using namespace std;
// const int MOD = 1000000007;




using ld = long double;
using P = std::complex<ld>;
using G = std::vector<P>;
const ld pi = std::acos(-1);
const ld eps = 1e-10;
const ld inf = 1e12;

ld cross(const P &a, const P &b) { return a.real() * b.imag() - a.imag() * b.real(); }
ld dot(const P &a, const P &b) { return a.real() * b.real() + a.imag() * b.imag(); }

/*
                    CCW

 -- BEHIND -- [a -- ON -- b] --- FRONT --

                    CW
 */
enum CCW_RESULT { CCW = +1, CW = -1, BEHIND = +2, FRONT = -2, ON = 0 };
int ccw(P a, P b, P c) {
    b -= a;
    c -= a;
    if (cross(b, c) > eps) return CCW;    // counter clockwise
    if (cross(b, c) < -eps) return CW;    // clockwise
    if (dot(b, c) < 0) return BEHIND;     // c--a--b on line
    if (norm(b) < norm(c)) return FRONT;  // a--b--c on line
    return ON;
}

namespace std {
bool operator<(const P &a, const P &b) {
    return std::abs(real(a) - real(b)) > eps ? real(a) < real(b) : imag(a) < imag(b);
}
}

struct L : public std::vector<P> {
    L(const P &a = P(), const P &b = P()) : std::vector<P>(2) {
        begin()[0] = a;
        begin()[1] = b;
    }

    // Ax + By + C = 0
    L(ld A, ld B, ld C) {
        if (std::abs(A) < eps && std::abs(B) < eps) {
            abort();
        } else if (std::abs(A) < eps) {
            *this = L(P(0, -C / B), P(1, -C / B));
        } else if (std::abs(B) < eps) {
            *this = L(P(-C / A, 0), P(-C / A, 1));
        } else {
            *this = L(P(0, -C / B), P(-C / A, 0));
        }
    }
};

struct C {
    P p;
    ld r;
    C(const P &p = 0, ld r = 0) : p(p), r(r) {}
};




bool intersectLL(const L &l, const L &m) {
    return std::abs(cross(l[1] - l[0], m[1] - m[0])) > eps ||  // non-parallel
           std::abs(cross(l[1] - l[0], m[0] - l[0])) < eps;    // same line
}
bool intersectLS(const L &l, const L &s) {
    return cross(l[1] - l[0], s[0] - l[0]) *  // s[0] is left of l
               cross(l[1] - l[0], s[1] - l[0]) <
           eps;  // s[1] is right of l
}
bool intersectLP(const L &l, const P &p) { return std::abs(cross(l[1] - p, l[0] - p)) < eps; }
bool intersectSS(const L &s, const L &t) {
    return ccw(s[0], s[1], t[0]) * ccw(s[0], s[1], t[1]) <= 0 &&
           ccw(t[0], t[1], s[0]) * ccw(t[0], t[1], s[1]) <= 0;
}
bool intersectSP(const L &s, const P &p) {
    return std::abs(s[0] - p) + std::abs(s[1] - p) - std::abs(s[1] - s[0]) <
           eps;  // triangle inequality
}

P projection(const L &l, const P &p) {
    ld t = dot(p - l[0], l[0] - l[1]) / norm(l[0] - l[1]);
    return l[0] + t * (l[0] - l[1]);
}
P reflection(const L &l, const P &p) { return p + (ld)2 * (projection(l, p) - p); }
ld distanceLP(const L &l, const P &p) { return std::abs(p - projection(l, p)); }
ld distanceLL(const L &l, const L &m) { return intersectLL(l, m) ? 0 : distanceLP(l, m[0]); }
ld distanceLS(const L &l, const L &s) {
    if (intersectLS(l, s)) return 0;
    return std::min(distanceLP(l, s[0]), distanceLP(l, s[1]));
}
ld distanceSP(const L &s, const P &p) {
    const P r = projection(s, p);
    if (intersectSP(s, r)) return std::abs(r - p);
    return std::min(std::abs(s[0] - p), std::abs(s[1] - p));
}
ld distanceSS(const L &s, const L &t) {
    if (intersectSS(s, t)) return 0;
    return std::min(std::min(distanceSP(s, t[0]), distanceSP(s, t[1])),
                    std::min(distanceSP(t, s[0]), distanceSP(t, s[1])));
}
P crosspointLL(const L &l, const L &m) {
    ld A = cross(l[1] - l[0], m[1] - m[0]);
    ld B = cross(l[1] - l[0], l[1] - m[0]);
    if (std::abs(A) < eps && std::abs(B) < eps) return m[0];  // same line
    if (std::abs(A) < eps) assert(false);                     // !!!PRECONDITION NOT SATISFIED!!!
    return m[0] + B / A * (m[1] - m[0]);
}


// 符号付二倍面積 abs(area2(G pol))/2.0 で求められる.
// polは頂点反時計回りで渡す
ld area2(const G& pol) {
    ld s = 0;
    int n = pol.size();
    for (int i = 0; i < n; ++i) s += cross(pol[i], pol[(i + 1) % n]);
    return s;
}


// 凸包
// == CWを != CCWに置換すると 退化した角を除く.
G andrewScan(G ps) {
    int N = ps.size(), k = 0;
    std::sort(ps.begin(), ps.end());
    G res(N * 2);
    for (int i = 0; i < N; i++) {
        while (k >= 2 && ccw(res[k - 2], res[k - 1], ps[i]) == CW) k--;
        res[k++] = ps[i];
    }
    int t = k + 1;
    for (int i = N - 2; i >= 0; i--) {
        while (k >= t && ccw(res[k - 2], res[k - 1], ps[i]) == CW) k--;
        res[k++] = ps[i];
    }
    res.resize(k - 1);
    return res;
}
//凸包終.


/*
// 凸多角形の直径
// 最近点対と競合.
#define curr(P, i) P[i]
#define next(P, i) P[(i + 1) % P.size()]
#define diff(P, i) (next(P, i) - curr(P, i))
ld convex_diameter(const G &pt) {
    const int n = pt.size();
    int is = 0, js = 0;
    for (int i = 1; i < n; ++i) {
        if (imag(pt[i]) > imag(pt[is])) is = i;
        if (imag(pt[i]) < imag(pt[js])) js = i;
    }
    ld maxd = norm(pt[is] - pt[js]);
    int i, maxi, j, maxj;
    i = maxi = is;
    j = maxj = js;
    do {
        if (cross(diff(pt, i), diff(pt, j)) >= 0)
            j = (j + 1) % n;
        else
            i = (i + 1) % n;
        if (norm(pt[i] - pt[j]) > maxd) {
            maxd = norm(pt[i] - pt[j]);
            maxi = i;
            maxj = j;
        }
    } while (i != is || j != js);
    return maxd; /* farthest pair is (maxi, maxj). */
/*
}
*/

//凸多角形の直径終.

// 凸多角形の切断. (左側のみ)
// 右側: lを逆に.
//@require intersection.cc
G convex_cut(const G& pol, const L& l) {
    G res;
    int n = pol.size();
    for (int i = 0; i < n; ++i) {
        P A = pol[i], B = pol[(i + 1) % n];
        if (ccw(l[0], l[1], A) != -1) res.push_back(A);
        if (ccw(l[0], l[1], A) * ccw(l[0], l[1], B) < 0) res.push_back(crosspointLL(L(A, B), l));
    }
    return res;
}
//凸多角形の切断終.

// 最近点対.
// O(N log N)
// [半開区間)iter渡し, x座標昇順.
// 凸多角形の直径と競合.
template <class iter>
std::tuple<ld, P, P> closest_pair(iter left, iter right) {
    int n = distance(left, right);

    if (n == 1) {
        return std::make_tuple(std::numeric_limits<ld>::max(), *left, *left);
    }

    if (n == 2) {
        if (left[0].imag() > left[1].imag()) swap(left[0], left[1]);
        return std::make_tuple(norm(left[0] - left[1]), left[0], left[1]);
    }

    iter middle = std::next(left, n / 2);
    ld x = middle->real();
    auto d = std::min(closest_pair(left, middle), closest_pair(middle, right));
    std::inplace_merge(left, middle, right,
                       [](const P &a, const P &b) { return a.imag() < b.imag(); });

    std::vector<iter> around;
    for (iter i = left; i != right; ++i) {
        ld dx = fabs(i->real() - x);
        ld &opt = std::get<0>(d);
        if (dx * dx >= opt) continue;
        for (auto j = around.rbegin(); j != around.rend(); ++j) {
            ld dx = i->real() - (**j).real();
            ld dy = i->imag() - (**j).imag();
            if (dy * dy >= opt) break;
            ld norm = dx * dx + dy * dy;
            if (opt > norm) {
                d = std::make_tuple(norm, *i, **j);
            }
        }
        around.push_back(i);
    }
    return d;
};

// 最近点対 終.


// 最小包含円.
// 期待値 O(N).
// [半開区間)iter渡し. seedは適当な整数or time(0).
template <class iter>
std::pair<P, ld> min_ball(iter left, iter right, int seed = 1333) {
    const int n = right - left;

    assert(n >= 1);
    if (n == 1) {
        return {*left, ld(0)};
    }

    std::mt19937 mt(seed);
    std::shuffle(left, right, mt);
    // std::random_shuffle(left, right); // simple but deprecated

    iter ps = left;
    using circle = std::pair<P, ld>;

    auto make_circle_3 = [](const P &a, const P &b, const P &c) -> circle {
        ld A = std::norm(b - c), B = std::norm(c - a), C = std::norm(a - b),
           S = cross(b - a, c - a);
        P p = (A * (B + C - A) * a + B * (C + A - B) * b + C * (A + B - C) * c) / (4 * S * S);
        ld r2 = std::norm(p - a);
        return {p, r2};
    };

    auto make_circle_2 = [](const P &a, const P &b) -> circle {
        P c = (a + b) / (ld)2;
        ld r2 = std::norm(a - c);
        return {c, r2};
    };

    auto in_circle = [](const P &a, const circle &c) -> bool {
        return std::norm(a - c.first) <= c.second + eps;
    };

    circle c = make_circle_2(ps[0], ps[1]);

    // MiniDisc
    for (int i = 2; i < n; ++i) {
        if (!in_circle(ps[i], c)) {
            // MiniDiscWithPoint
            c = make_circle_2(ps[0], ps[i]);
            for (int j = 1; j < i; ++j) {
                if (!in_circle(ps[j], c)) {
                    // MiniDiscWith2Points
                    c = make_circle_2(ps[i], ps[j]);
                    for (int k = 0; k < j; ++k) {
                        if (!in_circle(ps[k], c)) {
                            c = make_circle_3(ps[i], ps[j], ps[k]);
                        }
                    }
                }
            }
        }
    }
    return c;
}

// P:点 point x: .real() y: .imag()
// L:直線 lineF
// S:線分 section
// G:多角形 vector<P>

signed main() {
    int N;
    cin >> N;
    G g(N);
    rep(i, N){
        ld xi, yi;
        cin >> xi >> yi;
        g[i] = P(xi, yi);
    }
    cout << fixed << setprecision(10);
    sort(all(g));
    auto [o, rr] = min_ball(all(g), 1333);
    cout << o.real() << " " << o.imag() << " " << sqrt(rr) << endl;
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 6232
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;

#define print(s) cout << s;
#define println(s) cout << s << endl;
#define eps (1e-10)
#define bigint 2000000000
#define biglong 2000000000000000000L
#define rep(i,s,n) for(int i=s;i<(int)(n);i++)
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()//いるらしい
typedef pair<int, int> pii;
typedef vector<int> vi;


//ーーー入出力
template<typename T>
T next() {T a; cin >> a; return a;}

template<typename T>
vector<T> arrayInput(int n) {
    vector<T> a(n);
    for (int i = 0; i < n; i++) cin >> a[i];
    return a;
}

template<typename T>
vector<vector<T>> arrayInput(int h, int w) {
    vector<vector<T>> a(h, vector<T>(w));
    for (int i = 0; i < h; i++)
        for (int j = 0; j < w; j++)
            cin >> a[i][j];
    return a;
}


template <typename T>
void arrayPrint(const vector<T>& vec, bool blank = true) {
    int n = vec.size();
    for (int i = 0; i < n; ++i) {
        cout << vec[i];
        if (blank && i != n - 1) cout << ' ';
    }
    cout << '\n';
}
void arrayPrint(const vector<string>& vec, bool blank = false) {
    int n = vec.size();
    for (int i = 0; i < n; ++i) {
        cout << vec[i];
        if (blank && i != n - 1) cout << ' ';
    }
    cout << '\n';
}
void arrayPrint(const vector<bool>& vec, bool blank = true) {
    int n = vec.size();
    for (int i = 0; i < n; ++i) {
        cout << (vec[i] ? 'T' : 'F');
        if (blank && i != n - 1) cout << ' ';
    }
    cout << '\n';
}

template <typename T>
void arrayPrint(const vector<vector<T>>& mat, bool blank = true) {
    for (const auto& row : mat) {
        arrayPrint(row, blank);
    }
}
void arrayPrint(const vector<vector<string>>& mat, bool blank = false) {
    for (const auto& row : mat) {
        arrayPrint(row, blank);
    }
}

void arrayPrint(const vector<vector<bool>>& mat, bool blank = true) {
    for (const auto& row : mat) {
        arrayPrint(row, blank);
    }
}

template <class T> int sgn(T x) { return (x > 0) - (x < 0); }
template<class T>
struct Point {
    typedef Point P;
    T x, y;
    explicit Point(T x=0, T y=0) : x(x), y(y) {}
    bool operator<(P p) const { return tie(x,y) < tie(p.x,p.y); }
    bool operator==(P p) const { return tie(x,y)==tie(p.x,p.y); }
    P operator+(P p) const { return P(x+p.x, y+p.y); }
    P operator-(P p) const { return P(x-p.x, y-p.y); }
    P operator*(T d) const { return P(x*d, y*d); }
    P operator/(T d) const { return P(x/d, y/d); }
    T dot(P p) const { return x*p.x + y*p.y; }
    T cross(P p) const { return x*p.y - y*p.x; }
    T cross(P a, P b) const { return (a-*this).cross(b-*this); }
    T dist2() const { return x*x + y*y; }
    double dist() const { return sqrt((double)dist2()); }
    // angle to x-axis in interval [-pi, pi]
    double angle() const { return atan2(y, x); }
    P unit() const { return *this/dist(); } // makes dist()=1
    P perp() const { return P(-y, x); } // rotates +90 degrees
    P normal() const { return perp().unit(); }
    // returns point rotated 'a' radians ccw around the origin
    P rotate(double a) const {
        return P(x*cos(a)-y*sin(a),x*sin(a)+y*cos(a)); }
    friend ostream& operator<<(ostream& os, P p) {
        return os << "(" << p.x << "," << p.y << ")"; }
};
typedef Point<ld> P;
template<class P>
pair<int, P> lineInter(P s1, P e1, P s2, P e2) {
    auto d = (e1 - s1).cross(e2 - s2);
    if (d == 0) // if parallel
        return {-(s1.cross(e1, s2) == 0), P(0, 0)};
    auto p = s2.cross(e1, e2), q = s2.cross(e2, s1);
    return {1, (s1 * p + e1 * q) / d};
}

vector<P> convexHull(vector<P> pts) {
    if (sz(pts) <= 1) return pts;
    sort(all(pts));
    vector<P> h(sz(pts)+1);
    int s = 0, t = 0;
    for (int it = 2; it--; s = --t, reverse(all(pts)))
        for (P p : pts) {
            while (t >= s + 2 && h[t-2].cross(h[t-1], p) <= 0) t--;
            h[t++] = p;
        }
    return {h.begin(), h.begin() + t - (t == 2 && h[0] == h[1])};
}




vector<P> polygonCut(const vector<P>& poly, P s, P e) {//左を切り落とす
    vector<P> res;
    rep(i,0,sz(poly)) {
        P cur = poly[i], prev = i ? poly[i-1] : poly.back();
        auto a = s.cross(e, cur), b = s.cross(e, prev);
        if ((a < 0) != (b < 0))
            res.push_back(cur + (prev - cur) * (a / (a - b)));
        if (a < 0)
            res.push_back(cur);
    }
    return res;
}
template<class T>
T polygonArea2(vector<Point<T>>& v) {
    T a = v.back().cross(v[0]);
    rep(i,0,sz(v)-1) a += v[i].cross(v[i+1]);
    return a;
}


pair<P, P> closest(vector<P> v) {
    assert(sz(v) > 1);
    set<P> S;
    sort(all(v), [](P a, P b) { return a.y < b.y; });
    pair<ld, pair<P, P>> ret{(ld)LLONG_MAX, {P(), P()}};
    int j = 0;
    for (P p : v) {
        P d{1 + (ld)sqrt(ret.first), 0};
        while (v[j].y <= p.y - d.x) S.erase(v[j++]);
        auto lo = S.lower_bound(p - d), hi = S.upper_bound(p + d);
        for (; lo != hi; ++lo)
            ret = min(ret, {(*lo - p).dist2(), {*lo, p}});
        S.insert(p);
    }
    return ret.second;
}

double ccRadius(const P& A, const P& B, const P& C) {
    return (B-A).dist()*(C-B).dist()*(A-C).dist()/
            abs((B-A).cross(C-A))/2;
}
P ccCenter(const P& A, const P& B, const P& C) {
    P b = C-A, c = B-A;
    return A + (b*c.dist2()-c*b.dist2()).perp()/b.cross(c)/2;
}
pair<P, ld> mec(vector<P> ps) {
    shuffle(all(ps), mt19937(time(0)));
    P o = ps[0];
    double r = 0, EPS = 1 + 1e-8;
    rep(i,0,sz(ps)) if ((o - ps[i]).dist() > r * EPS) {
        o = ps[i], r = 0;
        rep(j,0,i) if ((o - ps[j]).dist() > r * EPS) {
            o = (ps[i] + ps[j]) / 2;
            r = (o - ps[i]).dist();
            rep(k,0,j) if ((o - ps[k]).dist() > r * EPS) {
                o = ccCenter(ps[i], ps[j], ps[k]);
                r = (o - ps[i]).dist();
            }
        }
    }
    return {o, r};
}

int main() {
    cin.tie(0) -> sync_with_stdio(0);
    cin.exceptions(cin.failbit);
    cout << fixed << setprecision(10) << endl;
    int n; cin >> n;
    vector<P> pts(n);
    for (int i=0;i<n;i++) {
        ld x,y;
        cin >> x >> y;
        pts[i] = P(x,y);
    }
    auto ans = mec(pts);
    cout << ans.first.x << " " << ans.first.y << " " << ans.second << endl;


}
accuracy: 1
time_ms: 30
memory_kb: 9416
final_rank: 9

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

typedef long long int64;

typedef long double db;
 
const db eps=1e-8L,pi=std::acos(-1.0L);

struct point{
  
  db x,y;
 
  point():x(),y(){}
  point(db _x,db _y):x(_x),y(_y){}

  db &operator[](int p){return p?y:x;}
  const db &operator[](int p)const{return p?y:x;}

  friend point operator+(const point &a,const point &b){return point(a.x+b.x,a.y+b.y);}
  friend point operator-(const point &a,const point &b){return point(a.x-b.x,a.y-b.y);}
  friend point operator*(const point &a,const db &b){return point(a.x*b,a.y*b);}
  friend point operator*(const db &b,const point &a){return point(a.x*b,a.y*b);}
  friend point operator/(const point &a,const db &b){return point(a.x/b,a.y/b);}
 
  friend db operator*(const point &a,const point &b){return a.x*b.x+a.y*b.y;}
  friend db operator%(const point &a,const point &b){return a.x*b.y-a.y*b.x;}
 
  friend bool operator==(const point &a,const point &b){return std::abs(a.x-b.x)<=eps&&std::abs(a.y-b.y)<=eps;}
  friend bool operator!=(const point &a,const point &b){return std::abs(a.x-b.x)>eps||std::abs(a.y-b.y)>eps;}
 
  db mod2()const{return x*x+y*y;}
  db mod()const{return std::sqrt(x*x+y*y);}
  db dis2(const point &a)const{return (*this-a).mod2();}
  db dis(const point &a)const{return (*this-a).mod();}
  point unit()const{return *this/mod();}

  db ang()const{return std::atan2(y,x);}
  db ang(const point &a)const{return std::atan2(*this%a,*this*a);}
  point norm()const{return point(-y,x);}
  point rot(const db &th)const{db s=std::sin(th),c=std::cos(th);return point(x*c-y*s,x*s+y*c);}

};

struct PolarAngleCmp{
  point o;
  PolarAngleCmp(const point &_o):o(_o){}
  bool operator()(const point &a,const point &b)const{
    db t=(a-o)%(b-o);
    return std::abs(t)<=eps?(a-o).mod2()<(b-o).mod2():t>eps;
  }
};

struct PointPairCmp{
  bool operator()(const point &a,const point &b)const{
    return std::abs(a.y-b.y)<=eps?a.x<b.x:a.y<b.y;
  }
};

struct line{
 
  point s,t;
 
  line():s(),t(){}
  line(point _s,point _t):s(_s),t(_t){}
 
  point &operator[](int p){return p?t:s;}
  const point &operator[](int p)const{return p?t:s;}

  db x(db y)const{return s.x+(y-s.y)/(t.y-s.y)*(t.x-s.x);}
  db y(db x)const{return s.y+(x-s.x)/(t.x-s.x)*(t.y-s.y);}
 
  point vec()const{return t-s;}
  db len2()const{return (t-s).mod2();}
  db len()const{return (t-s).mod();}

  point pro(const point &a)const{return s+(t-s)*((a-s)*(t-s)/(t-s).mod2());}
  point ref(const point &a)const{return 2*pro(a)-a;}
  db dis2(const point &a)const{return (pro(a)-a).mod2();}
  db dis(const point &a)const{return (pro(a)-a).mod();}

  // seg_in 不包括端点   seg_on 包括端点
  bool on(const point &a)const{return std::abs((a-s)%(a-t))<=eps;}
  bool seg_in(const point &a)const{return on(a)&&((a-s)*(a-t)<-eps);}
  bool seg_on(const point &a)const{return seg_in(a)||a==s||a==t;}

  // -1 重合   0 相交   1 平行
  int para(const line &b)const{
    const line &a=*this;
    return std::abs(a.vec()%b.vec())>eps?0:on(b.s)?-1:1;
  }

  // 包括端点
  int seg_cross(const line &b)const{
    const line &a=*this;
    if (std::max(a.s.x,a.t.x)+eps<std::min(b.s.x,b.t.x)) return 0;
    if (std::max(b.s.x,b.t.x)+eps<std::min(a.s.x,a.t.x)) return 0;
    if (std::max(a.s.y,a.t.y)+eps<std::min(b.s.y,b.t.y)) return 0;
    if (std::max(b.s.y,b.t.y)+eps<std::min(a.s.y,a.t.y)) return 0;
    auto sgn=[&](db x){return std::abs(x)<=eps?0:(x>0?1:-1);};
    if (sgn((a.s-b.s)%b.vec())*sgn((a.t-b.s)%b.vec())>0) return 0;
    if (sgn((b.s-a.s)%a.vec())*sgn((b.t-a.s)%a.vec())>0) return 0;
    return 1;
  }

  point cross(const line &b)const{
    const line &a=*this;
    point u=a.s-b.s,v=a.vec(),w=b.vec();
    return a.s+(w%u)/(v%w)*v;
  }
  
};

typedef std::vector<point> polygon;

// 1 在多边形内   0 不在多边形内   -1 在多边形边界上
int InPolygon(const polygon &a,const point &b){
  int res=0;
  for (int i=0;i<(int)a.size();++i){
    point u=a[i],v=a[(i+1)%(int)a.size()];
    if (line(u,v).seg_on(b)) return -1;
    if (std::abs(u.y-v.y)<=eps) continue;
    if (u.y>v.y) std::swap(u,v);
    if ((b-u)%(v-u)>eps) continue;
    if (b.y>u.y+eps&&b.y<=v.y+eps) res^=1;
  }
  return res&1;
}

// 1 在多边形内   0 不在多边形内   -1 在多边形边界上
int InConvex(const polygon &a,const point &b){
  if (b==a[0]) return -1;
  if ((a.back()-a[0])%(b-a[0])>eps) return 0;
  if (line(a.back(),a[0]).seg_on(b)) return -1;
  const point &o=a[0];
  int p=std::lower_bound(a.begin(),a.end()-1,b,PolarAngleCmp(o))-a.begin();
  if (line(a[p-1],a[p]).seg_on(b)) return -1;
  return (a[p]-a[p-1])%(b-a[p-1])>=-eps;
}

polygon ConvexHull(polygon a){
  point o=*std::min_element(a.begin(),a.end(),PointPairCmp());
  std::sort(a.begin(),a.end(),PolarAngleCmp(o));
  polygon res({a.front()});
  for (int i=1;i<(int)a.size();++i){
    for (;res.size()>=2&&(res.back()-res.end()[-2])%(a[i]-res.back())<=eps;res.pop_back());
    res.push_back(a[i]);
  }
  return res;
}

db Diameter(polygon a){
  db res=0;
  int n=a.size();
  a.push_back(a[0]);
  for (int i=0,j=1;i<n;++i){
    for (;(a[i+1]-a[i])%(a[j]-a[i])<(a[i+1]-a[i])%(a[j+1]-a[i])-eps;j=(j+1)%n);
    res=std::max({res,(a[j]-a[i]).mod2(),(a[j]-a[i+1]).mod2()});
  }
  return std::sqrt(res);
}

polygon Minkowski(polygon a,polygon b){
  int n=a.size(),m=b.size();
  polygon res({a[0]+b[0]});
  a.push_back(a[0]);b.push_back(b[0]);
  for (int i=0,j=0;;){
    (a[i+1]-a[i])%(b[j+1]-b[j])>eps?i=(i+1)%n:j=(j+1)%m;
    point t=a[i]+b[j];
    if (res.size()>=2&&std::abs((t-res.back())%(res.back()-res.end()[-2]))<=eps)
      res.pop_back();
    res.push_back(t);
    if (!i&&!j) break;
  }
  res.pop_back();
  return res;
}

// 半平面在直线逆时针方向
polygon HalfPlaneIntersection(std::vector<line> a){    // 半平面在直线逆时针方向
  const db inf=1e20L;
  a.emplace_back(point(-inf,-inf),point(inf,-inf));
  a.emplace_back(point(inf,-inf),point(inf,inf));
  a.emplace_back(point(inf,inf),point(-inf,inf));
  a.emplace_back(point(-inf,inf),point(-inf,-inf));
  std::sort(a.begin(),a.end(),[&](const line &a,const line &b){
    auto up=[&](const point &a){return a.y>eps||(std::abs(a.y)<=eps&&a.x>eps);};
    bool ua=up(a.vec()),ub=up(b.vec());
    if (ua!=ub) return ua<ub;
    db t=a.vec()%b.vec();
    if (std::abs(t)>eps) return t>eps;
    return (a[0]-b[0])%b.vec()<-eps;
  });
  std::deque<point> qc;
  std::deque<line> ql;
  ql.emplace_back(a[0]);
  auto popback=[&](const line &a){
    for (;!qc.empty()&&(qc.back()-a.s)%a.vec()>=-eps;)
      qc.pop_back(),ql.pop_back();
  };
  auto popfront=[&](const line &a){
    for (;!qc.empty()&&(qc.front()-a.s)%a.vec()>=-eps;)
      qc.pop_front(),ql.pop_front();
  };
  for (int i=1;i<(int)a.size();++i){
    if (a[i].vec()*a[i-1].vec()>=eps&&std::abs(a[i].vec()%a[i-1].vec())<=eps) continue;
    popback(a[i]);popfront(a[i]);
    if (!ql.empty()){
      if (std::abs(a[i].vec()%ql.back().vec())<=eps) return {};
      qc.push_back(a[i].cross(ql.back()));
    }
    ql.push_back(a[i]);
  }
  popback(ql.front());popfront(ql.back());
  qc.push_back(ql.front().cross(ql.back()));
  if (qc.size()<=2) return {};
  polygon res;
  for (auto t:qc) res.push_back(t);
  return res;
}

struct circle{

  point o;
  db r;

  circle():o(),r(){}
  circle(point _o,db _r):o(_o),r(_r){}

  point operator()(db th)const{return o+r*point(std::cos(th),std::sin(th));}

  bool in(const point &a)const{return o.dis2(a)<=r*r+eps;}
  bool on(const point &a)const{return std::abs(o.dis2(a)-r*r)<=eps;}

};

// 外接圆，共线时是三点的最小圆覆盖
circle CircumCircle(point a,point b,point c){
  if (std::abs((a-b)%(b-c))<=eps){
    if (PointPairCmp()(a,b)) std::swap(a,b);
    if (PointPairCmp()(a,c)) std::swap(a,c);
    if (PointPairCmp()(b,c)) std::swap(b,c);
    return circle((a+c)/2,a.dis(c)/2);
  }
  point u=(a+b)/2,v=(a+c)/2;
  line p(u,u+(b-a).norm()),q(v,v+(c-a).norm());
  point o=p.cross(q);
  return circle(o,o.dis(a));
}

// 内切圆，共线时可能出错
circle InCircle(const point &a,const point &b,const point &c){
  line p(a,a+(b-a).unit()+(c-a).unit());
  line q(b,b+(a-b).unit()+(c-b).unit());
  point o=p.cross(q);
  return circle(o,line(a,b).dis(o));
}

circle MinimumEnclosingCircle(polygon a){
  std::shuffle(a.begin(),a.end(),std::mt19937(time(0)));
  circle res(a[0],0);
  for (int i=1;i<(int)a.size();++i){
    if (res.in(a[i])) continue;
    res=circle(a[i],0);
    for (int j=0;j<i;++j){
      if (res.in(a[j])) continue;
      res=circle((a[i]+a[j])/2,(a[i]-a[j]).mod()/2);
      for (int k=0;k<j;++k){
        if (res.in(a[k])) continue;
        res=CircumCircle(a[i],a[j],a[k]);
      }
    }
  }
  return res;
}





db Area(const polygon &a){
  db res=0;
  for (int i=0;i<(int)a.size();++i)
    res+=a[i]%a[(i+1)%(int)a.size()];
  assert(std::abs(res)>=-eps);
  return res/2;
}

db Length(const polygon &a){
  db res=0;
  for (int i=0;i<(int)a.size();++i)
    res+=(a[i]-a[(i+1)%(int)a.size()]).mod();
  return res;
}

void work(){
  int n;
  std::cin>>n;
  polygon a(n);
  for (int i=0;i<n;++i) std::cin>>a[i].x>>a[i].y;
  auto c=MinimumEnclosingCircle(a);
  std::cout<<c.o.x<<' '<<c.o.y<<' ';
  std::cout<<c.r<<'\n';

  // point a,b,c;
  // std::cin>>a.x>>a.y>>b.x>>b.y>>c.x>>c.y;
  // circle ans=CircumCircle(a,b,c);
  // std::cout<<ans.o.x<<" "<<ans.o.y<<" "<<ans.r<<"\n";
}

int main(){
  std::ios::sync_with_stdio(0);
  std::cin.tie(0);
  std::cout<<std::fixed<<std::setprecision(12);
  std::cerr<<std::fixed<<std::setprecision(2);
  int T=1;
  // std::cin>>T;
  for (;T--;) work();
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 9436
final_rank: 10

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

typedef long long int64;

typedef long double db;
 
const db eps=1e-8L,pi=std::acos(-1.0L);

struct point{
  
  db x,y;
 
  point():x(),y(){}
  point(db _x,db _y):x(_x),y(_y){}

  db &operator[](int p){return p?y:x;}
  const db &operator[](int p)const{return p?y:x;}

  friend point operator+(const point &a,const point &b){return point(a.x+b.x,a.y+b.y);}
  friend point operator-(const point &a,const point &b){return point(a.x-b.x,a.y-b.y);}
  friend point operator*(const point &a,const db &b){return point(a.x*b,a.y*b);}
  friend point operator*(const db &b,const point &a){return point(a.x*b,a.y*b);}
  friend point operator/(const point &a,const db &b){return point(a.x/b,a.y/b);}
 
  friend db operator*(const point &a,const point &b){return a.x*b.x+a.y*b.y;}
  friend db operator%(const point &a,const point &b){return a.x*b.y-a.y*b.x;}
 
  friend bool operator==(const point &a,const point &b){return std::abs(a.x-b.x)<=eps&&std::abs(a.y-b.y)<=eps;}
  friend bool operator!=(const point &a,const point &b){return std::abs(a.x-b.x)>eps||std::abs(a.y-b.y)>eps;}
 
  db mod2()const{return x*x+y*y;}
  db mod()const{return std::sqrt(x*x+y*y);}
  db dis2(const point &a)const{return (*this-a).mod2();}
  db dis(const point &a)const{return (*this-a).mod();}
  point unit()const{return *this/mod();}

  db ang()const{return std::atan2(y,x);}
  db ang(const point &a)const{return std::atan2(*this%a,*this*a);}
  point norm()const{return point(-y,x);}
  point rot(const db &th)const{db s=std::sin(th),c=std::cos(th);return point(x*c-y*s,x*s+y*c);}

};

struct PolarAngleCmp{
  point o;
  PolarAngleCmp(const point &_o):o(_o){}
  bool operator()(const point &a,const point &b)const{
    db t=(a-o)%(b-o);
    return std::abs(t)<=eps?(a-o).mod2()<(b-o).mod2():t>eps;
  }
};

struct PointPairCmp{
  bool operator()(const point &a,const point &b)const{
    return std::abs(a.y-b.y)<=eps?a.x<b.x:a.y<b.y;
  }
};

struct line{
 
  point s,t;
 
  line():s(),t(){}
  line(point _s,point _t):s(_s),t(_t){}
 
  point &operator[](int p){return p?t:s;}
  const point &operator[](int p)const{return p?t:s;}

  db x(db y)const{return s.x+(y-s.y)/(t.y-s.y)*(t.x-s.x);}
  db y(db x)const{return s.y+(x-s.x)/(t.x-s.x)*(t.y-s.y);}
 
  point vec()const{return t-s;}
  db len2()const{return (t-s).mod2();}
  db len()const{return (t-s).mod();}

  point pro(const point &a)const{return s+(t-s)*((a-s)*(t-s)/(t-s).mod2());}
  point ref(const point &a)const{return 2*pro(a)-a;}
  db dis2(const point &a)const{return (pro(a)-a).mod2();}
  db dis(const point &a)const{return (pro(a)-a).mod();}

  // seg_in 不包括端点   seg_on 包括端点
  bool on(const point &a)const{return std::abs((a-s)%(a-t))<=eps;}
  bool seg_in(const point &a)const{return on(a)&&((a-s)*(a-t)<-eps);}
  bool seg_on(const point &a)const{return seg_in(a)||a==s||a==t;}

  // -1 重合   0 相交   1 平行
  int para(const line &b)const{
    const line &a=*this;
    return std::abs(a.vec()%b.vec())>eps?0:on(b.s)?-1:1;
  }

  // 包括端点
  int seg_cross(const line &b)const{
    const line &a=*this;
    if (std::max(a.s.x,a.t.x)+eps<std::min(b.s.x,b.t.x)) return 0;
    if (std::max(b.s.x,b.t.x)+eps<std::min(a.s.x,a.t.x)) return 0;
    if (std::max(a.s.y,a.t.y)+eps<std::min(b.s.y,b.t.y)) return 0;
    if (std::max(b.s.y,b.t.y)+eps<std::min(a.s.y,a.t.y)) return 0;
    auto sgn=[&](db x){return std::abs(x)<=eps?0:(x>0?1:-1);};
    if (sgn((a.s-b.s)%b.vec())*sgn((a.t-b.s)%b.vec())>0) return 0;
    if (sgn((b.s-a.s)%a.vec())*sgn((b.t-a.s)%a.vec())>0) return 0;
    return 1;
  }

  point cross(const line &b)const{
    const line &a=*this;
    point u=a.s-b.s,v=a.vec(),w=b.vec();
    return a.s+(w%u)/(v%w)*v;
  }
  
};

typedef std::vector<point> polygon;

// 1 在多边形内   0 不在多边形内   -1 在多边形边界上
int InPolygon(const polygon &a,const point &b){
  int res=0;
  for (int i=0;i<(int)a.size();++i){
    point p=a[i],q=a[(i+1)%(int)a.size()];
    if (line(p,q).seg_on(b)) return -1;
    if (std::abs(p.y-q.y)<=eps) continue;
    if (p.y>q.y) std::swap(p,q);
    if ((b-p)%(q-p)>eps) continue;
    if (b.y>p.y+eps&&b.y<=q.y+eps) res^=1;
  }
  return res&1;
}

// 1 在多边形内   0 不在多边形内   -1 在多边形边界上
int InConvex(const polygon &a,const point &b){
  if (b==a[0]) return -1;
  if ((a.back()-a[0])%(b-a[0])>eps) return 0;
  if (line(a.back(),a[0]).seg_on(b)) return -1;
  const point &o=a[0];
  int p=std::lower_bound(a.begin(),a.end()-1,b,PolarAngleCmp(o))-a.begin();
  if (line(a[p-1],a[p]).seg_on(b)) return -1;
  return (a[p]-a[p-1])%(b-a[p-1])>=-eps;
}

polygon ConvexHull(polygon a){
  point o=*std::min_element(a.begin(),a.end(),PointPairCmp());
  std::sort(a.begin(),a.end(),PolarAngleCmp(o));
  polygon res({a.front()});
  for (int i=1;i<(int)a.size();++i){
    for (;res.size()>=2&&(res.back()-res.end()[-2])%(a[i]-res.back())<=eps;res.pop_back());
    res.push_back(a[i]);
  }
  return res;
}

db Diameter(polygon a){
  db res=0;
  int n=a.size();
  a.push_back(a[0]);
  for (int i=0,j=1;i<n;++i){
    for (;(a[i+1]-a[i])%(a[j]-a[i])<(a[i+1]-a[i])%(a[j+1]-a[i])-eps;j=(j+1)%n);
    res=std::max({res,(a[j]-a[i]).mod2(),(a[j]-a[i+1]).mod2()});
  }
  return std::sqrt(res);
}

polygon Minkowski(polygon a,polygon b){
  int n=a.size(),m=b.size();
  polygon res({a[0]+b[0]});
  a.push_back(a[0]);b.push_back(b[0]);
  for (int i=0,j=0;;){
    (a[i+1]-a[i])%(b[j+1]-b[j])>eps?i=(i+1)%n:j=(j+1)%m;
    point t=a[i]+b[j];
    if (res.size()>=2&&std::abs((t-res.back())%(res.back()-res.end()[-2]))<=eps)
      res.pop_back();
    res.push_back(t);
    if (!i&&!j) break;
  }
  res.pop_back();
  return res;
}

// 半平面在直线逆时针方向
polygon HalfPlaneIntersection(std::vector<line> a){    // 半平面在直线逆时针方向
  const db inf=1e20L;
  a.emplace_back(point(-inf,-inf),point(inf,-inf));
  a.emplace_back(point(inf,-inf),point(inf,inf));
  a.emplace_back(point(inf,inf),point(-inf,inf));
  a.emplace_back(point(-inf,inf),point(-inf,-inf));
  std::sort(a.begin(),a.end(),[&](const line &a,const line &b){
    auto up=[&](const point &a){return a.y>eps||(std::abs(a.y)<=eps&&a.x>eps);};
    bool ua=up(a.vec()),ub=up(b.vec());
    if (ua!=ub) return ua<ub;
    db t=a.vec()%b.vec();
    if (std::abs(t)>eps) return t>eps;
    return (a[0]-b[0])%b.vec()<-eps;
  });
  std::deque<point> qc;
  std::deque<line> ql;
  ql.emplace_back(a[0]);
  auto popback=[&](const line &a){
    for (;!qc.empty()&&(qc.back()-a.s)%a.vec()>=-eps;)
      qc.pop_back(),ql.pop_back();
  };
  auto popfront=[&](const line &a){
    for (;!qc.empty()&&(qc.front()-a.s)%a.vec()>=-eps;)
      qc.pop_front(),ql.pop_front();
  };
  for (int i=1;i<(int)a.size();++i){
    if (a[i].vec()*a[i-1].vec()>=eps&&std::abs(a[i].vec()%a[i-1].vec())<=eps) continue;
    popback(a[i]);popfront(a[i]);
    if (!ql.empty()){
      if (std::abs(a[i].vec()%ql.back().vec())<=eps) return {};
      qc.push_back(a[i].cross(ql.back()));
    }
    ql.push_back(a[i]);
  }
  popback(ql.front());popfront(ql.back());
  qc.push_back(ql.front().cross(ql.back()));
  if (qc.size()<=2) return {};
  polygon res;
  for (auto &p:qc) res.push_back(p);
  return res;
}

struct circle{

  point o;
  db r;

  circle():o(),r(){}
  circle(point _o,db _r):o(_o),r(_r){}

  point operator()(db th)const{return o+r*point(std::cos(th),std::sin(th));}

  bool in(const point &a)const{return o.dis2(a)<=r*r+eps;}
  bool on(const point &a)const{return std::abs(o.dis2(a)-r*r)<=eps;}

  circle(point a,point b,point c){
    if (std::abs((a-b)%(b-c))<=eps){
      if (PointPairCmp()(a,b)) std::swap(a,b);
      if (PointPairCmp()(a,c)) std::swap(a,c);
      if (PointPairCmp()(b,c)) std::swap(b,c);
      o=(a+b)/2;
      r=(b-a).mod()/2;
    }else{
      point u=(a+b)/2,v=(a+c)/2;
      line p(u,u+(b-a).norm()),q(v,v+(c-a).norm());
      o=p.cross(q);
      r=o.dis(a);
    }
  }

};

circle MinimumEnclosingCircle(polygon a){
  std::shuffle(a.begin(),a.end(),std::mt19937(time(0)));
  circle res(a[0],0);
  for (int i=1;i<(int)a.size();++i){
    if (res.in(a[i])) continue;
    res=circle(a[i],0);
    for (int j=0;j<i;++j){
      if (res.in(a[j])) continue;
      res=circle((a[i]+a[j])/2,(a[i]-a[j]).mod()/2);
      for (int k=0;k<j;++k){
        if (res.in(a[k])) continue;
        res=circle(a[i],a[j],a[k]);
      }
    }
  }
  return res;
}





db Area(const polygon &a){
  db res=0;
  for (int i=0;i<(int)a.size();++i)
    res+=a[i]%a[(i+1)%(int)a.size()];
  assert(std::abs(res)>=-eps);
  return res/2;
}

db Length(const polygon &a){
  db res=0;
  for (int i=0;i<(int)a.size();++i)
    res+=(a[i]-a[(i+1)%(int)a.size()]).mod();
  return res;
}

void work(){
  int n;
  std::cin>>n;
  polygon a(n);
  for (int i=0;i<n;++i) std::cin>>a[i].x>>a[i].y;
  auto c=MinimumEnclosingCircle(a);
  std::cout<<c.o.x<<' '<<c.o.y<<' '<<c.r<<'\n';
}

int main(){
  std::ios::sync_with_stdio(0);
  std::cin.tie(0);
  std::cout<<std::fixed<<std::setprecision(12);
  std::cerr<<std::fixed<<std::setprecision(2);
  int T=1;
  // std::cin>>T;
  for (;T--;) work();
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 9436
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i< (n); ++i)
#define repi(i, a, b) for (int i = (a); i < (b); ++i)
#define all(x) (x).begin(), (x).end()
#define fore(i, a) for(auto &i:a)
using ll = long long;
using int64 = long long;
#define DEBUG(x) cerr << #x << ": "; for (auto _ : x) cerr << _ << " "; cerr << endl;
const int64 infll = (1LL << 62) - 1;
const int inf = (1 << 30) - 1;

struct IoSetup {
	IoSetup() {
		cin.tie(nullptr);
		ios::sync_with_stdio(false);
		cout << fixed << setprecision(10);
		cerr << fixed << setprecision(10);
	}
} iosetup;

template <typename T1, typename T2>
ostream& operator<<(ostream& os, const pair<T1, T2>& p) {
	os << p.first << " " << p.second;
	return os;
}

template <typename T1, typename T2>
istream& operator>>(istream& is, pair<T1, T2>& p) {
	is >> p.first >> p.second;
	return is;
}

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
	for (int i = 0; i < (int)v.size(); i++) {
		os << v[i] << (i + 1 != v.size() ? " " : "");
	}
	return os;
}

template <typename T>
istream& operator>>(istream& is, vector<T>& v) {
	for (T& in : v) is >> in;
	return is;
}

template <typename T1, typename T2>
inline bool chmax(T1& a, T2 b) {
	return a < b && (a = b, true);
}

template <typename T1, typename T2>
inline bool chmin(T1& a, T2 b) {
	return a > b && (a = b, true);
}

template <typename T = int64>
vector<T> make_v(size_t a) {
	return vector<T>(a);
}

template <typename T, typename... Ts>
auto make_v(size_t a, Ts... ts) {
	return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}

template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type fill_v(T& t, const V& v) {
	t = v;
}

template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type fill_v(T& t, const V& v) {
	for (auto& e : t) fill_v(e, v);
}

template <typename F>
struct FixPoint : F {
	explicit FixPoint(F&& f) : F(std::forward<F>(f)) {}

	template <typename... Args>
		decltype(auto) operator()(Args&&... args) const {
			return F::operator()(*this, std::forward<Args>(args)...);
		}
};

template <typename F>
inline decltype(auto) MFP(F&& f) {
	return FixPoint<F>{std::forward<F>(f)};
}
//Geometry
namespace geometry {
using Real = double;
const Real EPS = 1e-15;
const Real PI = acos(static_cast<Real>(-1));

enum { OUT, ON, IN };

inline int sign(const Real& r) { return r <= -EPS ? -1 : r >= EPS ? 1 : 0; }

inline bool equals(const Real& a, const Real& b) { return sign(a - b) == 0; }
}  // namespace geometry

namespace geometry {
using Point = complex<Real>;

istream& operator>>(istream& is, Point& p) {
  Real a, b;
  is >> a >> b;
  p = Point(a, b);
  return is;
}

ostream& operator<<(ostream& os, const Point& p) {
  return os << real(p) << " " << imag(p);
}

Point operator*(const Point& p, const Real& d) {
  return Point(real(p) * d, imag(p) * d);
}

// rotate point p counterclockwise by theta rad
Point rotate(Real theta, const Point& p) {
  return Point(cos(theta) * real(p) - sin(theta) * imag(p),
               sin(theta) * real(p) + cos(theta) * imag(p));
}

Real cross(const Point& a, const Point& b) {
  return real(a) * imag(b) - imag(a) * real(b);
}

Real dot(const Point& a, const Point& b) {
  return real(a) * real(b) + imag(a) * imag(b);
}

bool compare_x(const Point& a, const Point& b) {
  return equals(real(a), real(b)) ? imag(a) < imag(b) : real(a) < real(b);
}

bool compare_y(const Point& a, const Point& b) {
  return equals(imag(a), imag(b)) ? real(a) < real(b) : imag(a) < imag(b);
}

using Points = vector<Point>;
}  // namespace geometry

namespace geometry {
struct Line {
  Point a, b;

  Line() = default;

  Line(const Point& a, const Point& b) : a(a), b(b) {}

  Line(const Real& A, const Real& B, const Real& C) {  // Ax+By=C
    if (equals(A, 0)) {
      assert(!equals(B, 0));
      a = Point(0, C / B);
      b = Point(1, C / B);
    } else if (equals(B, 0)) {
      a = Point(C / A, 0);
      b = Point(C / A, 1);
    } else if (equals(C, 0)) {
      a = Point(0, C / B);
      b = Point(1, (C - A) / B);
    } else {
      a = Point(0, C / B);
      b = Point(C / A, 0);
    }
  }

  friend ostream& operator<<(ostream& os, Line& l) {
    return os << l.a << " to " << l.b;
  }

  friend istream& operator>>(istream& is, Line& l) { return is >> l.a >> l.b; }
};

using Lines = vector<Line>;
}  // namespace geometry

namespace geometry {
struct Segment : Line {
  Segment() = default;

  using Line::Line;
};

using Segments = vector<Segment>;
}  // namespace geometry
namespace geometry {
struct Circle {
  Point p;
  Real r{};

  Circle() = default;

  Circle(const Point& p, const Real& r) : p(p), r(r) {}
};

using Circles = vector<Circle>;
}  // namespace geometry
namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A
Point projection(const Line& l, const Point& p) {
  auto t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
  return l.a + (l.a - l.b) * t;
}
}  // namespace geometry

namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B
Point reflection(const Line& l, const Point& p) {
  return p + (projection(l, p) - p) * 2;
}
}  // namespace geometry

namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C
constexpr int COUNTER_CLOCKWISE = +1;
constexpr int CLOCKWISE = -1;
constexpr int ONLINE_BACK = +2;   // c-a-b
constexpr int ONLINE_FRONT = -2;  // a-b-c
constexpr int ON_SEGMENT = 0;     // a-c-b
int ccw(const Point& a, Point b, Point c) {
  b = b - a, c = c - a;
  if (sign(cross(b, c)) == +1) return COUNTER_CLOCKWISE;
  if (sign(cross(b, c)) == -1) return CLOCKWISE;
  if (sign(dot(b, c)) == -1) return ONLINE_BACK;
  if (norm(b) < norm(c)) return ONLINE_FRONT;
  return ON_SEGMENT;
}
}  // namespace geometry
namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool is_orthogonal(const Line& a, const Line& b) {
  return equals(dot(a.a - a.b, b.a - b.b), 0.0);
}
}  // namespace geometry
namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool is_parallel(const Line& a, const Line& b) {
  return equals(cross(a.b - a.a, b.b - b.a), 0.0);
}
}  // namespace geometry

namespace geometry {
bool is_intersect_ss(const Segment& s, const Segment& t) {
  return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 &&
         ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}
}  // namespace geometry
namespace geometry {
bool is_intersect_sp(const Segment& s, const Point& p) {
  return ccw(s.a, s.b, p) == ON_SEGMENT;
}
}  // namespace geometry

namespace geometry {
Point cross_point_ll(const Line& l, const Line& m) {
  Real A = cross(l.b - l.a, m.b - m.a);
  Real B = cross(l.b - l.a, l.b - m.a);
  if (equals(abs(A), 0) && equals(abs(B), 0)) return m.a;
  return m.a + (m.b - m.a) * B / A;
}
}  // namespace geometry
namespace geometry {
Real distance_sp(const Segment& s, const Point& p) {
  Point r = projection(s, p);
  if (is_intersect_sp(s, r)) return abs(r - p);
  return min(abs(s.a - p), abs(s.b - p));
}
}  // namespace geometry
namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D
Real distance_ss(const Segment& a, const Segment& b) {
  if (is_intersect_ss(a, b)) return 0;
  return min({distance_sp(a, b.a), distance_sp(a, b.b), distance_sp(b, a.a),
              distance_sp(b, a.b)});
}
}  // namespace geometry
namespace geometry {
using Polygon = vector<Point>;
using Polygons = vector<Polygon>;
}  // namespace geometry

namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_A
Real area(const Polygon& p) {
  int n = (int)p.size();
  Real A = 0;
  for (int i = 0; i < n; ++i) {
    A += cross(p[i], p[(i + 1) % n]);
  }
  return A * 0.5;
}
}  // namespace geometry
namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_B
bool is_convex_polygon(const Polygon& p) {
  int n = (int)p.size();
  for (int i = 0; i < n; i++) {
    if (ccw(p[(i + n - 1) % n], p[i], p[(i + 1) % n]) == CLOCKWISE)
      return false;
  }
  return true;
}
}  // namespace geometry
namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_C
int contains(const Polygon& Q, const Point& p) {
  bool in = false;
  for (int i = 0; i < Q.size(); i++) {
    Point a = Q[i] - p, b = Q[(i + 1) % Q.size()] - p;
    if (imag(a) > imag(b)) swap(a, b);
    if (sign(imag(a)) <= 0 && 0 < sign(imag(b)) && sign(cross(a, b)) < 0)
      in = !in;
    if (equals(cross(a, b), 0) && sign(dot(a, b)) <= 0) return ON;
  }
  return in ? IN : OUT;
}
}  // namespace geometry
namespace geometry {
int convex_polygon_contains(const Polygon& Q, const Point& p) {
  int N = (int)Q.size();
  Point g = (Q[0] + Q[N / 3] + Q[N * 2 / 3]) / 3.0;
  if (equals(imag(g), imag(p)) && equals(real(g), real(p))) return IN;
  Point gp = p - g;
  int l = 0, r = N;
  while (r - l > 1) {
    int mid = (l + r) / 2;
    Point gl = Q[l] - g;
    Point gm = Q[mid] - g;
    if (cross(gl, gm) > 0) {
      if (cross(gl, gp) >= 0 && cross(gm, gp) <= 0)
        r = mid;
      else
        l = mid;
    } else {
      if (cross(gl, gp) <= 0 && cross(gm, gp) >= 0)
        l = mid;
      else
        r = mid;
    }
  }
  r %= N;
  Real v = cross(Q[l] - p, Q[r] - p);
  return sign(v) == 0 ? ON : sign(v) == -1 ? OUT : IN;
}
}  // namespace geometry
namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_A
Polygon convex_hull(Polygon& p, bool strict = true) {
  int n = (int)p.size(), k = 0;
  if (n <= 2) return p;
  sort(begin(p), end(p), compare_x);
  vector<Point> ch(2 * n);
  auto check = [&](int i) {
    return sign(cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1])) <= -1 + strict;
  };
  for (int i = 0; i < n; ch[k++] = p[i++]) {
    while (k >= 2 && check(i)) --k;
  }
  for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) {
    while (k >= t && check(i)) --k;
  }
  ch.resize(k - 1);
  return ch;
}
}  // namespace geometry
namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_B
pair<int, int> convex_polygon_diameter(const Polygon& p) {
  int N = (int)p.size();
  int is = 0, js = 0;
  for (int i = 1; i < N; i++) {
    if (imag(p[i]) > imag(p[is])) is = i;
    if (imag(p[i]) < imag(p[js])) js = i;
  }
  Real maxdis = norm(p[is] - p[js]);

  int maxi, maxj, i, j;
  i = maxi = is;
  j = maxj = js;
  do {
    if (cross(p[(i + 1) % N] - p[i], p[(j + 1) % N] - p[j]) >= 0) {
      j = (j + 1) % N;
    } else {
      i = (i + 1) % N;
    }
    if (norm(p[i] - p[j]) > maxdis) {
      maxdis = norm(p[i] - p[j]);
      maxi = i;
      maxj = j;
    }
  } while (i != is || j != js);
  return minmax(maxi, maxj);
}
}  // namespace geometry
namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_C
// cut with a straight line l and return a convex polygon on the left
Polygon convex_polygon_cut(const Polygon& U, const Line& l) {
  Polygon ret;
  for (int i = 0; i < U.size(); i++) {
    const Point& now = U[i];
    const Point& nxt = U[(i + 1) % U.size()];
    auto cf = cross(l.a - now, l.b - now);
    auto cs = cross(l.a - nxt, l.b - nxt);
    if (sign(cf) >= 0) {
      ret.emplace_back(now);
    }
    if (sign(cf) * sign(cs) < 0) {
      ret.emplace_back(cross_point_ll(Line(now, nxt), l));
    }
  }
  return ret;
}
}  // namespace geometry
namespace geometry {
double closest_pair(Points &pts) {
	sort(pts.begin(), pts.end(), compare_x);
	vector<Point> buf(pts.size());
	auto dist2 = [](Point a, Point b){
		Point c = a-b;
		return c.real()*c.real()+c.imag()*c.imag();
	};
	function<double(int,int)> rec = [&](int l, int r) -> double {
		if (r - l <= 3) {
			double d2 = 1e300;
			for (int i = l; i < r; ++i)
				for (int j = i + 1; j < r; ++j)
					d2 = min(d2, dist2(pts[i], pts[j]));
			sort(pts.begin() + l, pts.begin() + r, compare_y);
			return d2;
		}

		int m = (l + r) / 2;
		double xmid = pts[m].real();
		double d2 = min(rec(l, m), rec(m, r));

		merge(pts.begin()+l, pts.begin()+m, pts.begin()+m, pts.begin()+r, buf.begin(), compare_y);
		copy(buf.begin(), buf.begin() + (r - l), pts.begin() + l);

		int sz = 0;
		for (int i = l; i < r; ++i) {
			if ((pts[i].real() - xmid) * (pts[i].real() - xmid) < d2)
				buf[sz++] = pts[i];
		}

		for (int i = 0; i < sz; ++i)
			for (int j = i - 1; j >= 0 && (buf[i].imag() - buf[j].imag()) * (buf[i].imag() - buf[j].imag()) < d2; --j)
				d2 = min(d2, dist2(buf[i], buf[j]));

		return d2;
	};

	return sqrt(rec(0, pts.size()));
}
}

namespace geometry {

bool in_circle(const Circle& c, const Point& p) {
  return abs(c.p - p) <= c.r + EPS;
}

Circle circle_from(const Point& A, const Point& B) {
  Point c = (A + B) / Real(2);
  Real r = abs(A - B) / Real(2);
  return Circle(c, r);
}

Circle circle_from(const Point& A, const Point& B, const Point& C) {
  Real a1 = real(B) - real(A);
  Real b1 = imag(B) - imag(A);
  Real c1 = (a1 * (real(A) + real(B)) + b1 * (imag(A) + imag(B))) / 2;

  Real a2 = real(C) - real(A);
  Real b2 = imag(C) - imag(A);
  Real c2 = (a2 * (real(A) + real(C)) + b2 * (imag(A) + imag(C))) / 2;

  Real det = a1 * b2 - a2 * b1;
  if (fabs(det) < EPS) return Circle(Point(0, 0), 1e18);

  Real cx = (c1 * b2 - c2 * b1) / det;
  Real cy = (a1 * c2 - a2 * c1) / det;
  Point center(cx, cy);
  Real radius = abs(center - A);
  return Circle(center, radius);
}

Circle welzl_rec(vector<Point>& P, vector<Point> R, int n) {
  if (n == 0 || R.size() == 3) {
    if (R.empty()) return Circle(Point(0, 0), 0);
    if (R.size() == 1) return Circle(R[0], 0);
    if (R.size() == 2) return circle_from(R[0], R[1]);
    return circle_from(R[0], R[1], R[2]);
  }

  Point p = P[n - 1];
  Circle D = welzl_rec(P, R, n - 1);
  if (in_circle(D, p)) return D;

  R.push_back(p);
  return welzl_rec(P, R, n - 1);
}

Circle minimum_enclosing_circle(Points P) {
  random_device rd;
  mt19937 g(rd());
  shuffle(P.begin(), P.end(), g); 
  return welzl_rec(P, {}, (int)P.size());
}

}  // namespace geometry
using namespace geometry;
int main(){
	ll n; cin >> n;
	Points p(n);
	rep(i, n)cin >> p[i];
	Circle c = minimum_enclosing_circle(p);
	cout << c.p << " " << c.r << endl;
}
accuracy: 1
time_ms: 60
memory_kb: 25536
final_rank: 20

code_snippet: // 非再帰版
// ここでのアルゴリズムで最小円が求まらない場合は、半径0の円が返される。最小円は存在するのだが、求まらない場合がありうるかも
#include <bits/stdc++.h>

using namespace std;



struct Point {
    double x, y;
};

struct Circle {
    Point c;    // 中心
    double r;   // 半径
};

// 距離
double dist(const Point &a, const Point &b) {
    return hypot(a.x - b.x, a.y - b.y);
}

// 点 p が円 c の内部にあるか（誤差を考慮して <= r+EPS）
bool inCircle(const Circle &c, const Point &p) {
    const double EPS = 1e-9;
    return dist(c.c, p) <= c.r + EPS;
}

// 2点を直径とする円
Circle circleFrom2Points(const Point &a, const Point &b) {
    Point center{ (a.x + b.x)/2.0, (a.y + b.y)/2.0 };
    double r = dist(a, b) / 2.0;
    return {center, r};
}

// 3点から外接円を作る
Circle circleFrom3Points(const Point &a, const Point &b, const Point &c) {
    // 外心を計算
    double d = 2*(a.x*(b.y-c.y) + b.x*(c.y-a.y) + c.x*(a.y-b.y));
    if (fabs(d) < 1e-12) {
        // ほぼ直線上の場合 → 最大距離の2点で直径円
        Circle c1 = circleFrom2Points(a, b);
        Circle c2 = circleFrom2Points(a, c);
        Circle c3 = circleFrom2Points(b, c);
        // 半径最小のものを返す
        Circle res = c1;
        if (c2.r > res.r) res = c2;
        if (c3.r > res.r) res = c3;
        return res;
    }
    double ux = ((a.x*a.x+a.y*a.y)*(b.y-c.y) +
                 (b.x*b.x+b.y*b.y)*(c.y-a.y) +
                 (c.x*c.x+c.y*c.y)*(a.y-b.y)) / d;
    double uy = ((a.x*a.x+a.y*a.y)*(c.x-b.x) +
                 (b.x*b.x+b.y*b.y)*(a.x-c.x) +
                 (c.x*c.x+c.y*c.y)*(b.x-a.x)) / d;
    Point center{ux, uy};
    double r = dist(center, a);
    return {center, r};
}


const int Remove = 0;
const int Compare = 1;
const int Ret = 2; 

// idxはPで使用する最初のindex
Circle welzl(vector<Point> &P) {
    int idx = 0;
    vector<Point> R(3);
    int Rnum = 0;
    vector<int> state(P.size(), 0);
    Circle D; 

    while (idx >= 0){
        
        if (idx >= P.size()){
            if (Rnum == 0) D = {{0,0}, 0};
            else if (Rnum == 1) D = {R[0], 0};
            else if (Rnum == 2) D = circleFrom2Points(R[0], R[1]);
            else if (Rnum == 3) D = circleFrom3Points(R[0], R[1], R[2]);
            else D = {{0,0}, 0};
            --idx;
        } else if (state[idx] == Remove){
            state[idx] = Compare;
            ++idx;
        } else if (state[idx] == Compare){
            if (inCircle(D, P[idx])){
                state[idx] = Remove; //修正
                --idx;
            } else {
                state[idx] = Ret;
                R[Rnum] = P[idx];
                ++Rnum;
                ++idx;
            }
        } else if (state[idx] == Ret){
            state[idx] = Remove;
            --Rnum;
            --idx;
        }
    }

    return D;
}
    





// メイン関数（入口）
// Circle minimumEnclosingCircle(vector<Point> P) {
//     return welzl(P);
// }

// 使用例
// 再帰本体
// welzl(P, {}, P.size())の戻り値は
// P = [(1,2)] --> c=(1,2), r = 0.0
// P =[(0,0), (1,0)] --> c=(0.5,0) r=0.5
// P =[(0,0), (1,0), (0,1)] --> c=(0.5,0.5) r=0.707

int main() {

    int n;
    cin >> n;
    vector<Point> P(n);
    for (int i = 0; i < n; i++) cin >> P[i].x >> P[i].y;
    random_shuffle(P.begin(), P.end());
    
    Circle C = welzl(P);

    printf("%.8f %.8f %.8f\n", C.c.x, C.c.y, C.r);

    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 5020
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
#endif
#ifndef ONLINE_JUDGE
#define _GLIBCXX_DEBUG
#include <iostream>
template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {return os<<'(' <<p.first<<", "<<p.second<<')';}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {os<<'[';for(auto it=v.begin();it!=v.end();++it){os<<*it; if(next(it)!=v.end()){os<<", ";}}return os<<']';}
template <typename T>
ostream& operator<<(ostream& os, const vector<vector<T>>& vv) {os<<"[\n";for(auto it=vv.begin();it!=vv.end();++it){os<<"  "<<*it;if(next(it)!=vv.end()){os<<",\n";}else{os<<"\n";}}return os<<"]";}
#define dump(x) cerr << #x << " = " << (x) << '\n'
#else
#define dump(x) (void)0
#endif
using ll = long long;
using ld = long double;
using P = pair<ll,ll>;
template<class T> using pq = priority_queue<T>;
template<class T> using pq_g = priority_queue<T, vector<T>, greater<T>>;
#define out(x) cout<<x<<'\n'
#define all(v) (v).begin(),(v).end()
#define rall(v) (v).rbegin(),(v).rend()
#define OVERLOAD_REP(_1,_2,_3,name,...) name
#define REP1(i,n) for (auto i = std::decay_t<decltype(n)>{}; (i) < (n); ++(i))
#define REP2(i, l, r) for (auto i = (l); (i) < (r); ++(i))
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP2, REP1)(__VA_ARGS__)
template<class T> inline bool chmin(T& a, T b) {if(a > b){a = b; return true;} else {return false;}};
template<class T> inline bool chmax(T& a, T b) {if(a < b){a = b; return true;} else {return false;}};
const ll INF=(1LL<<60);
const ll mod=998244353;
using Graph = vector<vector<ll>>;
using Network = vector<vector<pair<ll,ll>>>;
using Grid = vector<string>;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
const int dx2[8] = {1, 1,  1, 0,  0, -1, -1, -1};
const int dy2[8] = {1, 0, -1, 1, -1,  1,  0, -1};

// #include "../geo.hpp"

#pragma once

using D = long double;
const D EPS = 1e-12L;
const D PI = acosl(-1.0L);
using P2 = complex<D>;
struct L2{P2 a, b;};
struct S2{P2 a, b;};
using G2 = vector<P2>;

int sgn(D x){return (x>EPS)-(x<-EPS);}
int cmp(D a, D b){return sgn(a-b);}
bool eq(D a, D b){return cmp(a, b)==0;}
bool lt(D a, D b){return cmp(a, b)<0;}
bool le(D a, D b){return cmp(a, b)<=0;}
bool gt(D a, D b){return cmp(a, b)>0;}
bool ge(D a, D b){return cmp(a, b)>=0;}
bool eqP2(P2 a, P2 b){return eq(real(a), real(b)) && eq(imag(a), imag(b));}
bool ltP2(P2 a, P2 b) {
    return lt(real(a), real(b)) || (eq(real(a), real(b)) && lt(imag(a), imag(b)));
}

D dot(P2 a, P2 b) {return real(conj(a)*b);}
D cross(P2 a, P2 b) {return imag(conj(a)*b);}
int ccw(P2 a, P2 b, P2 c) {
    b-=a; c-=a;
    auto cr=cross(b, c), dt=dot(b, c);
    if (cr > EPS) return +1;       // counter clockwise
    if (cr < -EPS) return -1;      // clockwise
    if (dt < -EPS) return +2;         // c--a--b
    if (lt(norm(b), norm(c))) return -2; // a--b--c
    return 0;                  // a--c--b
}
int turn(P2 a, P2 b, P2 c) { return sgn(cross(b - a, c - a)); }

P2 rot(P2 a, D th) { return a*polar<D>(1, th); }
P2 rot90(P2 a) { return P2(-imag(a), real(a)); }
bool ltP2Arg(P2 a, P2 b) {
    auto up = [](P2 p) { return (imag(p) > 0 || (eq(imag(p), 0) && ge(real(p), 0))); };
    if (up(a) != up(b)) return up(a);
    if (!eq(cross(a, b), 0)) return cross(a, b) > 0;
    return lt(norm(a), norm(b));
}

inline void rd(P2& p) {D x, y; cin>>x>>y; p = P2(x, y);}
#define setp(n) cout<<setprecision(n)<<fixed
inline void pr(const P2& p) {setp(12); cout<<real(p)<<' '<<imag(p)<<'\n';}

// ----------------------------------------------------------------------------------

P2 proj(L2 l, P2 p) { P2 a=p-l.a, b=l.b-l.a; return l.a+b*dot(a, b)/norm(b);}
P2 refl(L2 l, P2 p) { return proj(l, p)*2.0L - p; }
bool isParallel(L2 l, L2 m){ return eq(cross(l.a-l.b, m.a-m.b), 0); }
bool isPerp(L2 l, L2 m){ return eq(dot(l.a-l.b, m.a-m.b), 0); }

bool isLL(L2 l, L2 m){ return !eq(cross(l.a-l.b, m.a-m.b), 0); }
bool isLS(L2 l, S2 s){ return turn(l.a, l.b, s.a)*turn(l.a, l.b, s.b)<=0; }
bool isSS(S2 s, S2 t) {
    return
    ccw(s.a,s.b,t.a)*ccw(s.a,s.b,t.b) <= 0 &&
    ccw(t.a,t.b,s.a)*ccw(t.a,t.b,s.b) <= 0;
}

P2 cpLL(L2 l, L2 m) {
    P2 a=l.b-l.a, b=m.b-m.a;
    D d=cross(a, b);
    if (eq(d, 0)) return P2(INF, INF); // parallel
    return l.a + a*cross(m.b-l.a,b)/d;
}

D distLP(L2 l, P2 p) { return abs(cross(l.b-l.a, p-l.a))/abs(l.b-l.a); }
D distSP(S2 s, P2 p) {
    P2 a=s.a, b=s.b;
    if (lt(dot(b-a, p-a), 0)) return abs(p-a);
    if (lt(dot(a-b, p-b), 0)) return abs(p-b);
    return distLP({a,b}, p);
}
D distSS(S2 s, S2 t) {
    if (isSS(s, t)) return 0;
    return min({distSP(s, t.a), distSP(s, t.b), distSP(t, s.a), distSP(t, s.b)});
}

D area(G2 g) {
    D s=0;
    int n=g.size();
    rep(i, n) s+=cross(g[i], g[(i+1)%n]);
    return s/2.0L;
}

bool isConvex(G2 g) {
    int n=g.size();
    if (n < 3) return false;
    int dir = 0;
    rep(i,n){
        int s = turn(g[i], g[(i+1)%n], g[(i+2)%n]);
        if (s == 0) return false; // -> continue : allows three points on a line
        if (dir == 0) dir = s;
        else if (dir*s < 0) return false;
    }
    return true;
}

int inG(G2 g, P2 p) {
    bool in=false;
    int n=g.size();
    rep(i, n) {
        P2 a=g[i], b=g[(i+1)%n];
        if (ccw(a, b, p) == 0) return 1; // on boundary
        if (a.imag() > b.imag()) swap(a, b);
        if (le(a.imag(), p.imag()) && lt(p.imag(), b.imag()) && turn(a, b, p) > 0) in=!in;
    }
    return in ? 2 : 0; // inside : outside
}

G2 hull(G2 g) {
    sort(all(g), ltP2);
    g.erase(unique(all(g), eqP2), g.end());
    if (g.size()<=1) return g;
    G2 lo, up;
    for (auto &p:g) {
        while (lo.size()>=2 && turn(lo[lo.size()-2], lo.back(), p)<=0) lo.pop_back(); //-> turn()<0 : allow three points on a line
        lo.push_back(p);
    }
    reverse(all(g));
    for (auto &p:g) {
        while (up.size()>=2 && turn(up[up.size()-2], up.back(), p)<=0) up.pop_back(); // -> turn()<0 : allow three points on a line
        up.push_back(p);
    }
    lo.pop_back(); up.pop_back();
    lo.insert(lo.end(), all(up));
    return lo;
}

pair<P2, P2> diameter(const G2& h) {
    int n=h.size();
    if(n==0) return {P2(0,0), P2(0,0)};
    if(n==1) return {h[0], h[0]};
    auto area2=[&](int i, int j, int k) {return abs(cross(h[j]-h[i], h[k]-h[i]));};
    D maxd=0;
    pair<P2, P2> res={h[0], h[0]};
    int j=1;
    rep(i, n) {
        int ni=(i+1)%n;
        while (gt(area2(i, ni, (j+1)%n), area2(i, ni, j))) j=(j+1)%n;
        if (gt(abs(h[i]-h[j]), maxd)) maxd=abs(h[i]-h[j]), res={h[i], h[j]};
        if (gt(abs(h[ni]-h[j]), maxd)) maxd=abs(h[ni]-h[j]), res={h[ni], h[j]};
    }
    return res;
}

// int inConvex(G2 h, P2 p) {
//     int n=h.size();
//     if (n==0) return 0;
//     if (n==1) return eqP2(h[0], p) ? 2 : 0;
//     if (n==2) return ccw(h[0], h[1], p)==0 && le(abs(h[0]-p)+abs(h[1]-p), abs(h[0]-h[1])) ? 2 : 0;
//     int left=1, right=n-1;
//     while (right-left>1) {
//         int mid=(left+right)/2;
//         if (turn(h[0], h[mid], p)<0) right=mid;
//         else left=mid;
//     }
//     if (turn(h[0], h[left], p)<0) return 0;
//     if (turn(h[left], h[right%n], p)<0) return 0;
//     if (turn(h[right%n], h[0], p)<0) return 0;
//     if (turn(h[0], h[left], p)==0 || turn(h[left], h[right%n], p)==0 || turn(h[right%n], h[0], p)==0) return 2;
//     return 1;
// }

G2 cutConvex(G2 h, L2 l) {
    int n=h.size();
    G2 res;
    if (n==0) return res;
    auto inside=[&](P2 p){ return turn(l.a, l.b, p) >= 0; };
    rep(i, n) {
        P2 a=h[i], b=h[(i+1)%n];
        bool ina=inside(a), inb=inside(b);
        if (ina&&inb) res.push_back(b);
        else if (ina&&!inb) {
            res.push_back(proj({a,b}, l.a));
        }
        else if (!ina&&inb) {
            res.push_back(proj({a,b}, l.a));
            res.push_back(b);
        }
    }
    return res;
}


pair<P2, P2> closestPair(G2 g) {
    auto ps = g;
    int n=ps.size();
    if (n < 2) return {P2(0,0), P2(0,0)};
    sort(all(ps), ltP2);
    D mind = norm(ps[0]-ps[1]);
    pair<P2, P2> res = {ps[0], ps[1]};
    set<pair<D,int>> box;
    int j=0;
    rep(i, n) {
        D xi=real(ps[i]), yi=imag(ps[i]);
        D rad = sqrtl(mind);
        while (j<i && gt(xi - real(ps[j]), rad)) {
            box.erase({imag(ps[j]), j});
            j++;
        }
        auto it = box.lower_bound({yi - rad, -1});
        for (; it != box.end() && le(it->first, yi + rad); ++it) {
            int k = it->second;
            D d = norm(ps[i]-ps[k]);
            if (lt(d, mind)) mind=d, res={ps[i], ps[k]}, rad = sqrtl(mind);
        }
        box.insert({yi, i});
    }
    return res;
}


struct C2 { P2 o; D r; };

C2 makeC2(P2 a, P2 b) {
    return C2{(a+b)/D(2), abs(a-b)/D(2)};
}
C2 makeC2(P2 a, P2 b, P2 c) {
    P2 B=b-a, C=c-a;
    D d=2*cross(B, C);
    if (eq(d, 0)) {
        D ab=norm(B), bc=norm(b-c), ca=norm(c-a);
        if (le(ab, bc) && le(ab, ca)) return makeC2(a, b);
        if (le(bc, ca)) return makeC2(b, c);
        return makeC2(c, a);
    }
    P2 o=a+(rot90(B)*norm(C)-rot90(C)*norm(B))/d;
    return C2{o, abs(o-a)};
}

C2 incircle(P2 a, P2 b, P2 c) {
    D ab=abs(b-a), bc=abs(c-b), ca=abs(a-c);
    P2 o=(a*bc+b*ca+c*ab)/(ab+bc+ca);
    D r=abs(cross(b-a, o-a))/abs(b-a);
    return C2{o, r};
}

vector<P2> cpCL(L2 l, C2 c) {
    vector<P2> res;
    P2 a=l.a-c.o, d=l.b-l.a;
    D A=norm(d), B=2*dot(a, d), C=norm(a)-c.r*c.r;
    D Dlt=B*B-4*A*C;
    if (lt(Dlt, 0)) return res;
    D s = le(Dlt, 0) ? 0 : sqrtl(max<D>(0, Dlt));
    D t1 = (-B - s)/(2*A), t2 = (-B + s)/(2*A);
    res.push_back(c.o + a + d*t1);
    if (gt(Dlt, 0)) res.push_back(c.o + a + d*t2);
    return res;
}

vector<P2> cpCC(C2 c1, C2 c2) {
    vector<P2> res;
    P2 d=c2.o-c1.o;
    D L=abs(d);
    if (eq(L, 0)) return res;
    D a=(c1.r*c1.r-c2.r*c2.r+L*L)/(2*L), h2=c1.r*c1.r-a*a;
    if (lt(h2, 0)) return res;
    P2 m=c1.o+d*(a/L), n=rot90(d)*( (lt(h2, 0) ? 0 : sqrtl(max<D>(0, h2))/L) );
    res.push_back(m-n);
    if (gt(h2, 0)) res.push_back(m+n);
    return res;
}

D isaCC(C2 c1, C2 c2) {
    D d=abs(c1.o-c2.o), r1=c1.r, r2=c2.r;
    if (ge(d, r1+r2)) return 0;
    if (le(d, abs(r1-r2))) {
        D r=min(r1, r2);
        return PI*r*r;
    }
    auto f = [&] (D z) { return max<D>(-1, min<D>(1, z)); };
    D a = 2*acosl(f((d*d+r1*r1-r2*r2)/(2*d*r1)));
    D b = 2*acosl(f((d*d+r2*r2-r1*r1)/(2*d*r2)));
    return 0.5L*(r1*r1*(a-sinl(a)) + r2*r2*(b-sinl(b)));
}

vector<L2> tangCP(C2 c, P2 p) {
    vector<L2> res;
    P2 v = p - c.o;
    D d2 = norm(v), r2 = c.r*c.r;
    if (lt(d2, r2)) return res;
    if (eq(d2, r2)) {
        res.push_back({c.o+v*(r2/d2), p});
        return res;
    }
    D h = c.r*sqrtl(max<D>(0, d2 - r2));
    P2 n1 = (v*r2 - rot90(v)*h)/d2;
    P2 n2 = (v*r2 + rot90(v)*h)/d2;
    res.push_back({c.o+n1, p});
    res.push_back({c.o+n2, p});
    return res;
}

vector<L2> tangCC(C2 c1, C2 c2) {
    vector<L2> res;
    P2 d = c2.o-c1.o;
    D L=abs(d);
    if (eq(L, 0)) return res;
    P2 e = d/L;
    auto add = [&] (int s) {
        D c=(s*c2.r - c1.r)/L;
        if (gt(c*c, 1)) return;
        D s2 = max<D>(0, 1 - c*c);
        if (eq(s2, 0)) {
            P2 n = e*c;
            res.push_back({c1.o-n*c1.r, c2.o-n*c2.r});
        } else {
            D s = sqrtl(s2);
            P2 n1 = e*c + rot90(e)*s;
            P2 n2 = e*c - rot90(e)*s;
            res.push_back({c1.o-n1*c1.r, c2.o-n1*c2.r});
            res.push_back({c1.o-n2*c1.r, c2.o-n2*c2.r});
        }
    };
    add(+1); // external
    add(-1); // internal
    return res;
}

C2 mec(G2 ps) {
    auto inC2=[&](C2 c, P2 p){ return le(abs(c.o - p), c.r); };
    mt19937_64 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());
    shuffle(all(ps), rng);
    int n=ps.size();
    if(n==0) return C2{P2(0,0), 0};
    C2 c{ps[0], 0};
    rep(i, n) {
        if (inC2(c, ps[i])) continue;
        c={ps[i], 0};
        rep(j, i) {
            if (inC2(c, ps[j])) continue;
            c=makeC2(ps[i], ps[j]);
            rep(k, j) {
                if (inC2(c, ps[k])) continue;
                c=makeC2(ps[i], ps[j], ps[k]);
            }
        }
    }
    return c;
}

vector<P2> cpSegs(vector<S2> ss) {
    struct E { D x; int t; D y, y1, y2; }; // t: 0=add(H), 1=query(V), 2=remove(H)
    vector<E> es; es.reserve(ss.size()*2);

    for(auto s: ss) {
        if (eq(s.a.imag(), s.b.imag())) {
            if (gt(s.a.real(), s.b.real())) swap(s.a, s.b);
            es.push_back({s.a.real(), 0, s.a.imag(), 0, 0});
            es.push_back({s.b.real(), 2, s.a.imag(), 0, 0});
        } else {
            if (gt(s.a.imag(), s.b.imag())) swap(s.a, s.b);
            es.push_back({s.a.real(), 1, 0, s.a.imag(), s.b.imag()});
        }
    }

    sort(all(es), [](E a, E b) {
        if (!eq(a.x, b.x)) return lt(a.x, b.x);
        return a.t < b.t;
    });

    multiset<D> active;
    vector<P2> res; res.reserve(ss.size());
    for (auto e : es) {
        if (e.t == 0) { // add
            active.insert(e.y);
        } else if (e.t == 2) { // remove
            auto it = active.find(e.y);
            if (it != active.end()) active.erase(it);
        } else { // query
            for (auto it = active.lower_bound(e.y1); it != active.end() && le(*it, e.y2); ++it) {
                res.push_back(P2(e.x, *it));
            }
        }
    }

    sort(all(res), ltP2);
    res.erase(unique(all(res), eqP2), res.end());
    return res;
}


// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/1/CGL_1_A
void Projection() {
    P2 a, b; rd(a); rd(b);
    L2 l = {a, b};
    ll q;cin>>q;
    while(q--) {
        P2 p; rd(p);
        pr(proj(l, p));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/1/CGL_1_B
void Reflection() {
    P2 a, b; rd(a); rd(b);
    L2 l = {a, b};
    ll q;cin>>q;
    while(q--) {
        P2 p; rd(p);
        pr(refl(l, p));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/1/CGL_1_C
void CounterClockwise() {
    P2 p0, p1;
    rd(p0); rd(p1);
    ll q; cin>>q;
    while(q--) {
        P2 p; rd(p);
        int res = ccw(p0, p1, p);
        if (res == +1) out("COUNTER_CLOCKWISE");
        else if (res == -1) out("CLOCKWISE");
        else if (res == +2) out("ONLINE_BACK");
        else if (res == -2) out("ONLINE_FRONT");
        else out("ON_SEGMENT");
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/1/CGL_2_A
void ParallelOrthogonal() {
    ll q;cin>>q;
    while(q--) {
        P2 p1, p2, p3, p4;
        rd(p1); rd(p2); rd(p3); rd(p4);
        if (isParallel({p1, p2}, {p3, p4})) out(2);
        else if(isPerp({p1, p2}, {p3, p4})) out(1);
        else out(0);
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/2/CGL_2_B
void IntersectionSS() {
    ll q;cin>>q;
    while(q--) {
        P2 p1, p2, p3, p4;
        rd(p1); rd(p2); rd(p3); rd(p4);
        S2 s1 = {p1, p2}, s2 = {p3, p4};
        out(isSS(s1, s2));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/2/CGL_2_C
void CrossPointSS() {
    ll q;cin>>q;
    while(q--) {
        P2 p1, p2, p3, p4;
        rd(p1); rd(p2); rd(p3); rd(p4);
        L2 s1 = {p1, p2}, s2 = {p3, p4};
        pr(cpLL(s1, s2));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/2/CGL_2_D
void DistanceSS() {
    ll q;cin>>q;
    while(q--) {
        P2 p1, p2, p3, p4;
        rd(p1); rd(p2); rd(p3); rd(p4);
        S2 s1 = {p1, p2}, s2 = {p3, p4};
        setp(12);
        out(distSS(s1, s2));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/3/CGL_3_A
void Area() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    setp(1);
    out(area(g));
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/3/CGL_3_B
void IsConvex() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    out(isConvex(g));
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/3/CGL_3_C
void PolygonPointContainment() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    ll q;cin>>q;
    while(q--) {
        P2 p; rd(p);
        out(inG(g, p));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/4/CGL_4_A
void ConvexHull() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    G2 h = hull(g);
    out(h.size());
    ll sx = INF, sy = INF;
    ll id = -1;
    rep(i, h.size()) {
        if (lt(imag(h[i]), sy)) {
            sx = real(h[i]);
            sy = imag(h[i]);
            id = i;
        }
        else if (eq(imag(h[i]), sy) && lt(real(h[i]), sx)) {
            sx = real(h[i]);
            sy = imag(h[i]);
            id = i;
        }
    }
    rep(i, h.size()) {
        ll ni = (id + i) % h.size();
        pr(h[ni]);
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/4/CGL_4_B
void DiameterOfConvexPolygon() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    auto [p1, p2] = diameter(g);
    setp(12);
    out(abs(p1 - p2));
    // todo
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/4/CGL_4_C
void ConvexCut() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    ll q;cin>>q;
    while(q--) {
        P2 a, b; rd(a); rd(b);
        L2 l = {a, b};
        G2 h = cutConvex(g, l);
        setp(12);
        out(area(h));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/5/CGL_5_A
void ClosestPair() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    auto [p1, p2] = closestPair(g);
    setp(12);
    out(abs(p1 - p2));
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/5/CGL_5_B
void MinimumEnclosingCircle() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    auto [c, r] = mec(g);
    pr(c);
    setp(12);
    out(r);
}


// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/6/CGL_6_A
void SegmentIntersections() {
    ll n;cin>>n;
    vector<S2> seg(n);
    rep(i, n) {
        P2 a, b; rd(a); rd(b);
        seg[i] = {a, b};
    }
    out(cpSegs(seg).size());
}


// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_A
void IntersectionOfCircles() {
    P2 o1, o2; D r1, r2;
    rd(o1); cin>>r1;
    rd(o2); cin>>r2;
    C2 c1={o1, r1}, c2={o2, r2};
    out(tangCC(c1, c2).size());
}

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_B
void IncircleOfTriangle() {
    P2 a, b, c; rd(a); rd(b); rd(c);
    auto [ic, ir] = incircle(a, b, c);
    pr(ic);
    setp(12);
    out(ir);
}

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_C
void CircumscribedCircleOfTriangle() {
    P2 a, b, c; rd(a); rd(b); rd(c);
    auto [cc, cr] = makeC2(a, b, c);
    pr(cc);
    setp(12);
    out(cr);
}

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_D
void CrossPointsCL() {
    P2 c; D r;
    rd(c); cin>>r;
    ll q;cin>>q;
    while(q--) {
        P2 a, b; rd(a); rd(b);
        L2 l = {a, b};
        auto ps = cpCL(l, {c, r});
        sort(all(ps), ltP2);
        pr(ps[0]);
        pr(ps[(ps.size()-1)]);
    }
}

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_E
void CrossPointsCC() {
    P2 o1, o2; D r1, r2;
    rd(o1); cin>>r1;
    rd(o2); cin>>r2;
    C2 c1={o1, r1}, c2={o2, r2};
    auto ps = cpCC(c1, c2);
    sort(all(ps), ltP2);
    pr(ps[0]);
    pr(ps[(ps.size()-1)]);
}

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_F
void TangentToCircle() {
    P2 p, c; D r;
    rd(p);
    rd(c); cin>>r;
    C2 c1={c, r};
    auto ls = tangCP(c1, p);
    vector<P2> ps;
    for (auto l : ls) {
        ps.push_back(l.a);
    }
    sort(all(ps), ltP2);
    for (auto p : ps) pr(p);
}

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_G
void CommonTangent() {
    P2 o1, o2; D r1, r2;
    rd(o1); cin>>r1;
    rd(o2); cin>>r2;
    C2 c1={o1, r1}, c2={o2, r2};
    auto ls = tangCC(c1, c2);
    vector<P2> ps;
    for (auto l : ls) {
        ps.push_back(l.a);
    }
    sort(all(ps), ltP2);
    for (auto p : ps) pr(p);
}

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_H
// void IntersectionCP() {
//     ll n;cin>>n;
//     D r; cin>>r;
//     C2 c = {P2(0, 0), r};
//     G2 g(n);
//     rep(i, n) rd(g[i]);
//     out(isaCP(c, g));
// }

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_I
void AreaOfIntersectionBetweenTwoCircles() {
    P2 o1, o2; D r1, r2;
    rd(o1); cin>>r1;
    rd(o2); cin>>r2;
    C2 c1={o1, r1}, c2={o2, r2};
    setp(12);
    out(isaCC(c1, c2));
}

int main() {
    cin.tie(0);
    ios_base::sync_with_stdio(false);

    // Projection();
    // Reflection();
    // CounterClockwise();

    // ParallelOrthogonal();
    // IntersectionSS();
    // CrossPointSS();
    // DistanceSS();

    // Area();
    // IsConvex();
    // PolygonPointContainment();

    // ConvexHull();
    // DiameterOfConvexPolygon();
    // ConvexCut();

    // ClosestPair();
    MinimumEnclosingCircle();

    // SegmentIntersections();

    // IntersectionOfCircles();
    // IncircleOfTriangle();
    // CircumscribedCircleOfTriangle();
    // CrossPointsCL();
    // CrossPointsCC();
    // TangentToCircle();
    // CommonTangent();
    // IntersectionCP();
    // AreaOfIntersectionBetweenTwoCircles();
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 9472
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
#endif
#ifndef ONLINE_JUDGE
#define _GLIBCXX_DEBUG
#include <iostream>
template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {return os<<'(' <<p.first<<", "<<p.second<<')';}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {os<<'[';for(auto it=v.begin();it!=v.end();++it){os<<*it; if(next(it)!=v.end()){os<<", ";}}return os<<']';}
template <typename T>
ostream& operator<<(ostream& os, const vector<vector<T>>& vv) {os<<"[\n";for(auto it=vv.begin();it!=vv.end();++it){os<<"  "<<*it;if(next(it)!=vv.end()){os<<",\n";}else{os<<"\n";}}return os<<"]";}
#define dump(x) cerr << #x << " = " << (x) << '\n'
#else
#define dump(x) (void)0
#endif
using ll = long long;
using ld = long double;
using P = pair<ll,ll>;
template<class T> using pq = priority_queue<T>;
template<class T> using pq_g = priority_queue<T, vector<T>, greater<T>>;
#define out(x) cout<<x<<'\n'
#define all(v) (v).begin(),(v).end()
#define rall(v) (v).rbegin(),(v).rend()
#define OVERLOAD_REP(_1,_2,_3,name,...) name
#define REP1(i,n) for (auto i = std::decay_t<decltype(n)>{}; (i) < (n); ++(i))
#define REP2(i, l, r) for (auto i = (l); (i) < (r); ++(i))
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP2, REP1)(__VA_ARGS__)
template<class T> inline bool chmin(T& a, T b) {if(a > b){a = b; return true;} else {return false;}};
template<class T> inline bool chmax(T& a, T b) {if(a < b){a = b; return true;} else {return false;}};
const ll INF=(1LL<<60);
const ll mod=998244353;
using Graph = vector<vector<ll>>;
using Network = vector<vector<pair<ll,ll>>>;
using Grid = vector<string>;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
const int dx2[8] = {1, 1,  1, 0,  0, -1, -1, -1};
const int dy2[8] = {1, 0, -1, 1, -1,  1,  0, -1};

// #include "../geo.hpp"

using D = long double;
const D EPS = 1e-12L;
using P2 = complex<D>;
struct L2{P2 a, b;};
struct S2{P2 a, b;};
using G2 = vector<P2>;

int sgn(D x){return (x>EPS)-(x<-EPS);}
int cmp(D a, D b){return sgn(a-b);}
bool eq(D a, D b){return cmp(a, b)==0;}
bool lt(D a, D b){return cmp(a, b)<0;}
bool le(D a, D b){return cmp(a, b)<=0;}
bool gt(D a, D b){return cmp(a, b)>0;}
bool ge(D a, D b){return cmp(a, b)>=0;}
bool eqP2(P2 a, P2 b){return eq(real(a), real(b)) && eq(imag(a), imag(b));}
bool ltP2(P2 a, P2 b) {
    return lt(real(a), real(b)) || (eq(real(a), real(b)) && lt(imag(a), imag(b)));
}

D dot(P2 a, P2 b) {return real(conj(a)*b);}
D cross(P2 a, P2 b) {return imag(conj(a)*b);}
int ccw(P2 a, P2 b, P2 c) {
    b-=a; c-=a;
    auto cr=cross(b, c), dt=dot(b, c);
    if (cr > EPS) return +1;       // counter clockwise
    if (cr < -EPS) return -1;      // clockwise
    if (dt < -EPS) return +2;         // c--a--b
    if (lt(norm(b), norm(c))) return -2; // a--b--c
    return 0;                  // a--c--b
}
int turn(P2 a, P2 b, P2 c) { return sgn(cross(b - a, c - a)); }

P2 rot(P2 a, D th) { return a*polar<D>(1, th); }
P2 rot90(P2 a) { return P2(-imag(a), real(a)); }

inline void rd(P2& p) {D x, y; cin>>x>>y; p = P2(x, y);}
inline void pr(const P2& p) {cout<<setprecision(12)<<fixed<<real(p)<<' '<<imag(p)<<'\n';}


P2 proj(L2 l, P2 p) { P2 a=p-l.a, b=l.b-l.a; return l.a+b*dot(a, b)/norm(b);}
P2 refl(L2 l, P2 p) { return proj(l, p)*2.0L - p; }
bool isParallel(L2 l, L2 m){ return eq(cross(l.a-l.b, m.a-m.b), 0); }
bool isPerp(L2 l, L2 m){ return eq(dot(l.a-l.b, m.a-m.b), 0); }

bool isLL(L2 l, L2 m){ return !eq(cross(l.a-l.b, m.a-m.b), 0); }
bool isLS(L2 l, S2 s){ return turn(l.a, l.b, s.a)*turn(l.a, l.b, s.b)<=0; }
bool isSS(S2 s, S2 t) {
    return
    ccw(s.a,s.b,t.a)*ccw(s.a,s.b,t.b) <= 0 &&
    ccw(t.a,t.b,s.a)*ccw(t.a,t.b,s.b) <= 0;
}

P2 cpLL(L2 l, L2 m) {
    P2 a=l.b-l.a, b=m.b-m.a;
    D d=cross(a, b);
    if (eq(d, 0)) return P2(INF, INF); // parallel
    return l.a + a*cross(m.b-l.a,b)/d;
}

D distLP(L2 l, P2 p) { return abs(cross(l.b-l.a, p-l.a))/abs(l.b-l.a); }
D distSP(S2 s, P2 p) {
    P2 a=s.a, b=s.b;
    if (lt(dot(b-a, p-a), 0)) return abs(p-a);
    if (lt(dot(a-b, p-b), 0)) return abs(p-b);
    return distLP({a,b}, p);
}
D distSS(S2 s, S2 t) {
    if (isSS(s, t)) return 0;
    return min({distSP(s, t.a), distSP(s, t.b), distSP(t, s.a), distSP(t, s.b)});
}

D area(G2 g) {
    D s=0;
    int n=g.size();
    rep(i, n) s+=cross(g[i], g[(i+1)%n]);
    return s/2.0L;
}

bool isConvex(G2 g) {
    int n=g.size();
    if (n < 3) return false;
    int dir = 0;
    rep(i,n){
        int s = turn(g[i], g[(i+1)%n], g[(i+2)%n]);
        if (s == 0) return false; // -> continue : allows three points on a line
        if (dir == 0) dir = s;
        else if (dir*s < 0) return false;
    }
    return true;
}

int inG(G2 g, P2 p) {
    bool in=false;
    int n=g.size();
    rep(i, n) {
        P2 a=g[i], b=g[(i+1)%n];
        if (ccw(a, b, p) == 0) return 2; // on boundary
        if (a.imag() > b.imag()) swap(a, b);
        if (le(a.imag(), p.imag()) && lt(p.imag(), b.imag()) && turn(a, b, p) > 0) in=!in;
    }
    return in ? 1 : 0; // inside : outside
}

G2 hull(G2 g) {
    sort(all(g), ltP2);
    g.erase(unique(all(g), eqP2), g.end());
    if (g.size()<=1) return g;
    G2 lo, up;
    for (auto &p:g) {
        while (lo.size()>=2 && turn(lo[lo.size()-2], lo.back(), p)<=0) lo.pop_back(); //-> turn()<0 : allow three points on a line
        lo.push_back(p);
    }
    reverse(all(g));
    for (auto &p:g) {
        while (up.size()>=2 && turn(up[up.size()-2], up.back(), p)<=0) up.pop_back(); // -> turn()<0 : allow three points on a line
        up.push_back(p);
    }
    lo.pop_back(); up.pop_back();
    lo.insert(lo.end(), all(up));
    return lo;
}

pair<P2, P2> diameter(const G2& h) {
    int n=h.size();
    if(n==0) return {P2(0,0), P2(0,0)};
    if(n==1) return {h[0], h[0]};
    auto area2=[&](int i, int j, int k) {return abs(cross(h[j]-h[i], h[k]-h[i]));};
    D maxd=0;
    pair<P2, P2> res={h[0], h[0]};
    int j=1;
    rep(i, n) {
        int ni=(i+1)%n;
        while (gt(area2(i, ni, (j+1)%n), area2(i, ni, j))) j=(j+1)%n;
        if (gt(abs(h[i]-h[j]), maxd)) maxd=abs(h[i]-h[j]), res={h[i], h[j]};
        if (gt(abs(h[ni]-h[j]), maxd)) maxd=abs(h[ni]-h[j]), res={h[ni], h[j]};
    }
    return res;
}

// int inConvex(G2 h, P2 p) {
//     int n=h.size();
//     if (n==0) return 0;
//     if (n==1) return eqP2(h[0], p) ? 2 : 0;
//     if (n==2) return ccw(h[0], h[1], p)==0 && le(abs(h[0]-p)+abs(h[1]-p), abs(h[0]-h[1])) ? 2 : 0;
//     int left=1, right=n-1;
//     while (right-left>1) {
//         int mid=(left+right)/2;
//         if (turn(h[0], h[mid], p)<0) right=mid;
//         else left=mid;
//     }
//     if (turn(h[0], h[left], p)<0) return 0;
//     if (turn(h[left], h[right%n], p)<0) return 0;
//     if (turn(h[right%n], h[0], p)<0) return 0;
//     if (turn(h[0], h[left], p)==0 || turn(h[left], h[right%n], p)==0 || turn(h[right%n], h[0], p)==0) return 2;
//     return 1;
// }

G2 cutConvex(G2 h, L2 l) {
    int n=h.size();
    G2 res;
    if (n==0) return res;
    auto inside=[&](P2 p){ return turn(l.a, l.b, p) >= 0; };
    rep(i, n) {
        P2 a=h[i], b=h[(i+1)%n];
        bool ina=inside(a), inb=inside(b);
        if (ina&&inb) res.push_back(b);
        else if (ina&&!inb) {
            res.push_back(proj({a,b}, l.a));
        }
        else if (!ina&&inb) {
            res.push_back(proj({a,b}, l.a));
            res.push_back(b);
        }
    }
    return res;
}


pair<P2, P2> closestPair(G2 g) {
    auto ps = g;
    int n=ps.size();
    if (n < 2) return {P2(0,0), P2(0,0)};
    sort(all(ps), ltP2);
    D mind = norm(ps[0]-ps[1]);
    pair<P2, P2> res = {ps[0], ps[1]};
    set<pair<D,int>> box;
    int j=0;
    rep(i, n) {
        D xi=real(ps[i]), yi=imag(ps[i]);
        D rad = sqrtl(mind);
        while (j<i && gt(xi - real(ps[j]), rad)) {
            box.erase({imag(ps[j]), j});
            j++;
        }
        auto it = box.lower_bound({yi - rad, -1});
        for (; it != box.end() && le(it->first, yi + rad); ++it) {
            int k = it->second;
            D d = norm(ps[i]-ps[k]);
            if (lt(d, mind)) mind=d, res={ps[i], ps[k]}, rad = sqrtl(mind);
        }
        box.insert({yi, i});
    }
    return res;
}

struct C2 { P2 c; D r; };

C2 makeC2(P2 a, P2 b) {
    return C2{(a+b)/D(2), abs(a-b)/D(2)};
}
C2 makeC2(P2 a, P2 b, P2 c) {
    P2 B=b-a, C=c-a;
    D d=2*cross(B, C);
    if (eq(d, 0)) {
        D ab=norm(B), bc=norm(b-c), ca=norm(c-a);
        if (le(ab, bc) && le(ab, ca)) return makeC2(a, b);
        if (le(bc, ca)) return makeC2(b, c);
        return makeC2(c, a);
    }
    P2 o=a+(rot90(B)*norm(C)-rot90(C)*norm(B))/d;
    return C2{o, abs(o-a)};
}

C2 mec(G2 ps) {
    auto inC2=[&](C2 c, P2 p){ return le(abs(c.c - p), c.r); };
    mt19937_64 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());
    shuffle(all(ps), rng);
    int n=ps.size();
    if(n==0) return C2{P2(0,0), 0};
    C2 c{ps[0], 0};
    rep(i, n) {
        if (inC2(c, ps[i])) continue;
        c={ps[i], 0};
        rep(j, i) {
            if (inC2(c, ps[j])) continue;
            c=makeC2(ps[i], ps[j]);
            rep(k, j) {
                if (inC2(c, ps[k])) continue;
                c=makeC2(ps[i], ps[j], ps[k]);
            }
        }
    }
    return c;
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/1/CGL_1_A
void Projection() {
    P2 a, b; rd(a); rd(b);
    L2 l = {a, b};
    ll q;cin>>q;
    while(q--) {
        P2 p; rd(p);
        pr(proj(l, p));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/1/CGL_1_B
void Reflection() {
    P2 a, b; rd(a); rd(b);
    L2 l = {a, b};
    ll q;cin>>q;
    while(q--) {
        P2 p; rd(p);
        pr(refl(l, p));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/1/CGL_1_C
void CounterClockwise() {
    P2 p0, p1;
    rd(p0); rd(p1);
    ll q; cin>>q;
    while(q--) {
        P2 p; rd(p);
        int res = ccw(p0, p1, p);
        if (res == +1) out("COUNTER_CLOCKWISE");
        else if (res == -1) out("CLOCKWISE");
        else if (res == +2) out("ONLINE_BACK");
        else if (res == -2) out("ONLINE_FRONT");
        else out("ON_SEGMENT");
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/1/CGL_2_A
void ParallelOrthogonal() {
    ll q;cin>>q;
    while(q--) {
        P2 p1, p2, p3, p4;
        rd(p1); rd(p2); rd(p3); rd(p4);
        if (isParallel({p1, p2}, {p3, p4})) out(2);
        else if(isPerp({p1, p2}, {p3, p4})) out(1);
        else out(0);
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/2/CGL_2_B
void IntersectionSS() {
    ll q;cin>>q;
    while(q--) {
        P2 p1, p2, p3, p4;
        rd(p1); rd(p2); rd(p3); rd(p4);
        S2 s1 = {p1, p2}, s2 = {p3, p4};
        out(isSS(s1, s2));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/2/CGL_2_C
void CrossPointSS() {
    ll q;cin>>q;
    while(q--) {
        P2 p1, p2, p3, p4;
        rd(p1); rd(p2); rd(p3); rd(p4);
        L2 s1 = {p1, p2}, s2 = {p3, p4};
        pr(cpLL(s1, s2));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/2/CGL_2_D
void DistanceSS() {
    ll q;cin>>q;
    while(q--) {
        P2 p1, p2, p3, p4;
        rd(p1); rd(p2); rd(p3); rd(p4);
        S2 s1 = {p1, p2}, s2 = {p3, p4};
        cout<<setprecision(12)<<fixed;
        out(distSS(s1, s2));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/3/CGL_3_A
void Area() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    cout<<setprecision(12)<<fixed;
    out(area(g));
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/3/CGL_3_B
void IsConvex() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    out(isConvex(g));
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/3/CGL_3_C
void PolygonPointContainment() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    ll q;cin>>q;
    while(q--) {
        P2 p; rd(p);
        out(inG(g, p));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/4/CGL_4_A
void ConvexHull() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    G2 h = hull(g);
    out(h.size());
    rep(i, h.size()) pr(h[i]);
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/4/CGL_4_B
void DiameterOfConvexPolygon() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    auto [p1, p2] = diameter(g);
    cout<<setprecision(12)<<fixed;
    out(abs(p1 - p2));
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/4/CGL_4_C
void ConvexCut() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    ll q;cin>>q;
    while(q--) {
        P2 a, b; rd(a); rd(b);
        L2 l = {a, b};
        G2 h = cutConvex(g, l);
        cout<<setprecision(12)<<fixed;
        out(area(h));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/5/CGL_5_A
void ClosestPair() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    auto [p1, p2] = closestPair(g);
    cout<<setprecision(12)<<fixed;
    out(abs(p1 - p2));
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/5/CGL_5_B
void MinimumEnclosingCircle() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    auto [c, r] = mec(g);
    pr(c);
    cout<<setprecision(12)<<fixed;
    out(r);
}


// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/6/CGL_6_A
// void SegmentIntersections() {
//     // todo;
// }

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_A
// void IntersectionOfCircles() {
//     P2 c1, c2; D r1, r2;
//     rd(c1); cin>>r1;
//     rd(c2); cin>>r2;
//     C2 c1={c1, r1}, c2={c2, r2};
//     out(isCC(c1, c2));
// }

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_B
// void IncircleOfTriangle() {
//     P2 a, b, c; rd(a); rd(b); rd(c);
//     auto [ic, ir] = incircle(a, b, c);
//     pr(ic);
//     cout<<setprecision(12)<<fixed;
//     out(ir);
// }

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_C
// void CircumscribedCircleOfTriangle() {
//     P2 a, b, c; rd(a); rd(b); rd(c);
//     auto [cc, cr] = circumcircle(a, b, c);
//     pr(cc);
//     cout<<setprecision(12)<<fixed;
//     out(cr);
// }

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_D
// void CrossPointsCL() {
//     P2 c; D r;
//     rd(c); cin>>r;
//     ll q;cin>>q;
//     while(q--) {
//         P2 a, b; rd(a); rd(b);
//         L2 l = {a, b};
//         auto ps = cpCL(l, {c, r});
//         sort(all(ps), ltP2);
//         pr(ps[0]);
//         pr(ps[(ps.size()-1)]);
//     }
// }

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_E
// void CrossPointsCC() {
//     P2 c1, c2; D r1, r2;
//     rd(c1); cin>>r1;
//     rd(c2); cin>>r2;
//     C2 c1={c1, r1}, c2={c2, r2};
//     auto ps = cpCC(c1, c2);
//     sort(all(ps), ltP2);
//     pr(ps[0]);
//     pr(ps[(ps.size()-1)]);
// }

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_F
// void TangentToCircle() {
//     P2 p, c; D r;
//     rd(p);
//     rd(c); cin>>r;
//     C2 c1={c, r};
//     auto ps = tangentCP(c1, p);
//     sort(all(ps), ltP2);
//     pr(ps[0]);
//     pr(ps[(ps.size()-1)]);
// }

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_G
// void CommonTangent() {
//     P2 c1, c2; D r1, r2;
//     rd(c1); cin>>r1;
//     rd(c2); cin>>r2;
//     C2 c1={c1, r1}, c2={c2, r2};
//     auto ls = tangentCC(c1, c2);
//     vector<P2> ps;
//     for (auto l : ls) {
//         ps.push_back(l.a);
//         ps.push_back(l.b);
//     }
//     sort(all(ps), ltP2);
//     for (auto p : ps) pr(p);
// }

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_H
// void IntersectionCP() {
//     ll n;cin>>n;
//     D r; cin>>r;
//     C2 c = {P2(0, 0), r};
//     G2 g(n);
//     rep(i, n) rd(g[i]);
//     out(isaCP(c, g));
// }

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_I
// void AreaOfIntersectionBetweenTwoCircles() {
//     P2 c1, c2; D r1, r2;
//     rd(c1); cin>>r1;
//     rd(c2); cin>>r2;
//     C2 c1={c1, r1}, c2={c2, r2};
//     cout<<setprecision(12)<<fixed;
//     out(isaCC(c1, c2));
// }

int main() {
    cin.tie(0);
    ios_base::sync_with_stdio(false);

    // Projection();
    // Reflection();
    // CounterClockwise();

    // ParallelOrthogonal();
    // IntersectionSS();
    // CrossPointSS();
    // DistanceSS();

    // Area();
    // IsConvex();
    // PolygonPointContainment();

    // ConvexHull();
    // DiameterOfConvexPolygon();
    // ConvexCut();

    // ClosestPair();
    MinimumEnclosingCircle();

    // SegmentIntersections();

    // IntersectionOfCircles();
    // IncircleOfTriangle();
    // CircumscribedCircleOfTriangle();
    // CrossPointsCL();
    // CrossPointsCC();
    // TangentToCircle();
    // CommonTangent();
    // IntersectionCP();
    // AreaOfIntersectionBetweenTwoCircles();
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 9444
final_rank: 19

code_snippet: #include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <climits>
#include <unordered_map>
#include <queue>
#include <deque>
#include <math.h>
#include <limits.h>
#include <set>
#include <stack>
#include <map>
#include <bits/stdc++.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <cmath>
#define Lt Line<T>
#define Pt Point<T>
#define ll long long



//#define double long double
using namespace std;


const ll N=2e4+10,M=1e6+10,MOD=998244353;

typedef std::pair<ll,ll> pii;
typedef std::pair<ll,std::pair<ll,ll> > piii;


//ll n,m;

using ld = long double;
const ld PI = acos(-1);
const ld EPS = 1e-7;
const ld INF = numeric_limits<ld>::max();
#define cc(x) cout << fixed << setprecision(x);

ld fgcd(ld x, ld y) { // 实数域gcd
    return abs(y) < EPS ? abs(x) : fgcd(y, fmod(x, y));
}
template<class T, class S> bool equal(T x, S y) {
    return -EPS < x - y && x - y < EPS;
}
template<class T> int sign(T x) {
    if (-EPS < x && x < EPS) return 0;
    return x < 0 ? -1 : 1;
}



template<class T> struct Point { // 在C++17下使用 emplace_back 绑定可能会导致CE！
    T x, y;
    Point(T x_ = 0, T y_ = 0) : x(x_), y(y_) {} // 初始化
    template<class U> operator Point<U>() { // 自动类型匹配
        return Point<U>(U(x), U(y));
    }
    Point &operator+=(Point p) & { return x += p.x, y += p.y, *this; }
    Point &operator+=(T t) & { return x += t, y += t, *this; }
    Point &operator-=(Point p) & { return x -= p.x, y -= p.y, *this; }
    Point &operator-=(T t) & { return x -= t, y -= t, *this; }
    Point &operator*=(T t) & { return x *= t, y *= t, *this; }
    Point &operator/=(T t) & { return x /= t, y /= t, *this; }
    Point operator-() const { return Point(-x, -y); }
    friend Point operator+(Point a, Point b) { return a += b; }
    friend Point operator+(Point a, T b) { return a += b; }
    friend Point operator-(Point a, Point b) { return a -= b; }
    friend Point operator-(Point a, T b) { return a -= b; }
    friend Point operator*(Point a, T b) { return a *= b; }
    friend Point operator*(T a, Point b) { return b *= a; }
    friend Point operator/(Point a, T b) { return a /= b; }
    friend bool operator<(Point a, Point b) {
        return equal(a.x, b.x) ? a.y < b.y - EPS : a.x < b.x - EPS;
    }
    friend bool operator>(Point a, Point b) { return b < a; }
    friend bool operator==(Point a, Point b) { return !(a < b) && !(b < a); }
    friend bool operator!=(Point a, Point b) { return a < b || b < a; }
    friend auto &operator>>(istream &is, Point &p) {
        return is >> p.x >> p.y;
    }
    friend auto &operator<<(ostream &os, Point p) {
        return os << "(" << p.x << ", " << p.y << ")";
    }
};
template<class T> struct Line {
    Point<T> a, b;
    Line(Point<T> a_ = Point<T>(), Point<T> b_ = Point<T>()) : a(a_), b(b_) {}
    template<class U> operator Line<U>() { // 自动类型匹配
        return Line<U>(Point<U>(a), Point<U>(b));
    }
    friend auto &operator<<(ostream &os, Line l) {
        return os << "<" << l.a << ", " << l.b << ">";
    }
};

using Pd = Point<ld>;
using Ld = Line<ld>;

template<class T> T cross(Point<T> a, Point<T> b) { // 叉乘
    return a.x * b.y - a.y * b.x;
}
template<class T> T cross(Point<T> p1, Point<T> p2, Point<T> p0) { // 叉乘 (p1 - p0) x (p2 - p0);
    return cross(p1 - p0, p2 - p0);
}

template<class T> T dot(Point<T> a, Point<T> b) { // 点乘
    return a.x * b.x + a.y * b.y;
}
template<class T> T dot(Point<T> p1, Point<T> p2, Point<T> p0) { // 点乘 (p1 - p0) * (p2 - p0);
    return dot(p1 - p0, p2 - p0);
}

template <class T> ld dis(T x1, T y1, T x2, T y2) {
    ld val = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
    return sqrt(val);
}
template <class T> ld dis(Point<T> a, Point<T> b) {
    return dis(a.x, a.y, b.x, b.y);
}

template<class T> Point<T> rotate(Point<T> p1, Point<T> p2) { // 旋转
    Point<T> vec = p1 - p2;
    return {-vec.y, vec.x};
}

Point<ld> rotate(Point<ld> p, ld rad) {
    return {p.x * cos(rad) - p.y * sin(rad), p.x * sin(rad) + p.y * cos(rad)};
}

Point<ld> rotate(Point<ld> a, Point<ld> b, ld rad) {
    ld x = (a.x - b.x) * cos(rad) + (a.y - b.y) * sin(rad) + b.x;
    ld y = (b.x - a.x) * sin(rad) + (a.y - b.y) * cos(rad) + b.y;
    return {x, y};
}

template<class T> bool onLine(Point<T> a, Point<T> b, Point<T> c) {
    return sign(cross(b, a, c)) == 0;
}
template<class T> bool onLine(Point<T> p, Line<T> l) {
    return onLine(p, l.a, l.b);
}

template<class T> bool lineParallel(Line<T> p1, Line<T> p2) {
    return sign(cross(p1.a - p1.b, p2.a - p2.b)) == 0;
}
template<class T> bool lineVertical(Line<T> p1, Line<T> p2) {
    return sign(dot(p1.a - p1.b, p2.a - p2.b)) == 0;
}
template<class T> bool same(Line<T> l1, Line<T> l2) {
    return lineParallel(Line{l1.a, l2.b}, {l1.b, l2.a}) &&
           lineParallel(Line{l1.a, l2.a}, {l1.b, l2.b}) && lineParallel(l1, l2);
}

template<class T> ld disPointToLine(Point<T> p, Line<T> l) {
    ld ans = cross(p, l.a, l.b);
    return abs(ans) / dis(l.a, l.b); // 面积除以底边长
}

template<class T> bool pointOnSegment(Point<T> p, Line<T> l) { // 端点也算作在直线上
    return sign(cross(p, l.a, l.b)) == 0 && min(l.a.x, l.b.x) <= p.x && p.x <= max(l.a.x, l.b.x) &&
           min(l.a.y, l.b.y) <= p.y && p.y <= max(l.a.y, l.b.y);
}

template<class T> bool segmentIntersection(Line<T> l1, Line<T> l2) {
    auto [s1, e1] = l1;
    auto [s2, e2] = l2;
    auto A = max(s1.x, e1.x), AA = min(s1.x, e1.x);
    auto B = max(s1.y, e1.y), BB = min(s1.y, e1.y);
    auto C = max(s2.x, e2.x), CC = min(s2.x, e2.x);
    auto D = max(s2.y, e2.y), DD = min(s2.y, e2.y);
    return A >= CC && B >= DD && C >= AA && D >= BB &&
           sign(cross(s1, s2, e1) * cross(s1, e1, e2)) == 1 &&
           sign(cross(s2, s1, e2) * cross(s2, e2, e1)) == 1;
}//其中重叠、相交于端点均视为不相交。

Pd lineIntersection(Ld l1, Ld l2) {
    ld val = cross(l2.b - l2.a, l1.a - l2.a) / cross(l2.b - l2.a, l1.a - l1.b);
    return l1.a + (l1.b - l1.a) * val;
}

pair<Pd, ld> pointToLine(Pd p, Ld l) {
    Pd ans = lineIntersection({p, p + rotate(l.a, l.b)}, l);
    return {ans, dis(p, ans)};
}

pair<Pd, ld> pointToSegment(Pd p, Ld l) {
    if (sign(dot(p, l.b, l.a)) == -1) { // 特判到两端点的距离
        return {l.a, dis(p, l.a)};
    } else if (sign(dot(p, l.a, l.b)) == -1) {
        return {l.b, dis(p, l.b)};
    }
    return pointToLine(p, l);
}

ld DisSegToSeg(Ld l1,Ld l2)
{
    // if(lineParallel(l1,l2)) 
    // {
    //     auto [t1,ans1]=pointToSegment(l1.a,l2);
    //     return ans1;
    // }
    if(segmentIntersection(l1,l2)) return 0.0;
    auto [t1,ans1]=pointToSegment(l1.a,l2);
    auto [t2,ans2]=pointToSegment(l1.b,l2);
    auto [t3,ans3]=pointToSegment(l2.a,l1);
    auto [t4,ans4]=pointToSegment(l2.b,l1);
    //cout<<ans1<<' '<<ans2<<' '<<ans3<<' '<<ans4<<'\n';
    return min(min(ans1,ans2),min(ans3,ans4));
}

template<class T> ld area(vector<Point<T>> P) {
    int n = P.size();
    ld ans = 0;
    for (int i = 0; i < n; i++) {
        ans += cross(P[i], P[(i + 1) % n]);
    }
    return ans / 2.0;
}

template<class T> vector<Point<T>> staticConvexHull(vector<Point<T>> A, int flag = 1) {
    int n = A.size();
    if (n <= 2) { // 特判
        return A;
    }
    vector<Point<T>> ans(n * 2);
    sort(A.begin(), A.end());
    int now = -1;
    for (int i = 0; i < n; i++) { // 维护下凸包
        while (now > 0 && cross(A[i], ans[now], ans[now - 1]) < 0) {
            now--;
        }
        ans[++now] = A[i];
    }
    int pre = now;
    for (int i = n - 2; i >= 0; i--) { // 维护上凸包
        while (now > pre && cross(A[i], ans[now], ans[now - 1]) <= 0) {
            now--;
        }
        ans[++now] = A[i];
    }
    ans.resize(now);
    sort(ans.begin(),ans.end());
    ans.erase(unique(ans.begin(),ans.end()),ans.end());
    return ans;
}



template<class T> T sqr(T x) {
    return x * x;
}

template<class T> T disEx(Pt a1,Pt a2)
{
    return (a1.x-a2.x)*(a1.x-a2.x)+(a1.y-a2.y)*(a1.y-a2.y);
}

// 计算最小包围圆（最小圆覆盖）
// 输入：点集的迭代器范围 [left, right)，随机种子 seed
// 输出：pair<圆心, 半径平方>
template <class T>
std::pair<Point<T>, ld> min_ball(vector<Pt> A, int seed = 1333) {
    
    const int n = A.size();  // 点的数量

    assert(n >= 1);  // 至少需要1个点
    
    // 特殊情况处理：只有1个点
    if (n == 1) {
        return {A[0], ld(0)};  // 圆就是点本身，半径为0
    }

    // 随机数生成器
    std::mt19937 mt(seed);
    // 随机打乱点集顺序 - 这是保证O(n)期望时间复杂度的关键
    std::shuffle(A.begin(), A.end(), mt);

    vector<Pt> &ps=A;

    using circle = std::pair<Pt, ld>;  // 圆类型：圆心 + 半径平方

    // 通过三个点构造圆的lambda函数
    auto make_circle_3 = [](const Pt &a, const Pt &b, const Pt &c) -> circle {
        // 使用三角形外心公式计算圆心
        ld A = disEx(b , c),  // |BC|²
           B = disEx(c , a),  // |CA|²  
           C = disEx(a , b),  // |AB|²
           S = cross(b - a, c - a);  // 三角形面积的2倍
        
        // 外心坐标公式（重心坐标形式）
        Pt p = (A * (B + C - A) * a + B * (C + A - B) * b + C * (A + B - C) * c) / (4 * S * S);
        ld r2 = disEx(p , a);  // 半径的平方
        return {p, r2};
    };

    // 通过两个点构造圆的lambda函数（以两点为直径的圆）
    auto make_circle_2 = [](const Pt &a, const Pt &b) -> circle {
        Pt c = (a + b) / (ld)2;  // 圆心为两点中点
        ld r2 = disEx(a , c);  // 半径平方
        return {c, r2};
    };

    // 判断点是否在圆内的lambda函数
    auto in_circle = [](const Pt &a, const circle &c) -> bool {
        // 判断点到圆心的距离平方是否 <= 半径平方 + 容误差
        return disEx(a , c.first) <= c.second + EPS;
    };

    // 初始化：用前两个点构造初始圆
    circle c = make_circle_2(ps[0], ps[1]);

    // 主循环：逐个处理剩余的点
    for (int i = 2; i < n; ++i) {
        // 如果当前点不在当前圆内，需要更新圆
        if (!in_circle(ps[i], c)) {
            // MiniDiscWithPoint: 新圆必须包含当前点ps[i]
            c = make_circle_2(ps[0], ps[i]);  // 初始尝试：用第一个点和当前点构造圆
            
            // 检查前面的点是否都在新圆内
            for (int j = 1; j < i; ++j) {
                if (!in_circle(ps[j], c)) {
                    // MiniDiscWith2Points: 新圆必须包含ps[i]和ps[j]
                    c = make_circle_2(ps[i], ps[j]);  // 用当前两个点构造圆
                    
                    // 检查更前面的点
                    for (int k = 0; k < j; ++k) {
                        if (!in_circle(ps[k], c)) {
                            // 三个点确定唯一圆
                            c = make_circle_3(ps[i], ps[j], ps[k]);
                        }
                    }
                }
            }
        }
        // 如果当前点在圆内，直接跳过（概率O(1/k)，这是算法高效的关键）
    }
    return c;
}


int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);

    cc(12);
    
    int n; cin>>n;
    vector<Pd> z(n);
    for(auto &t:z) cin>>t;
    auto [ans,r]=min_ball(z);

    cout<<ans.x<<' '<<ans.y<<' '<<sqrt(r)<<'\n';
    
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 9748
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'

const double eps = 0;
struct Point{
    double x,y;
    bool operator<(Point p){
        if(x!=p.x)return x<p.x;
        return y<p.y;
    }
};
struct cir{
    Point o;
    double r;
};
vector<Point>p(100010);
int n;
double dis(Point a,Point b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
cir get(Point a,Point b,Point c){
    double a1 = b.x-a.x,a2 = c.x-a.x,b1 = b.y-a.y,b2 = c.y-a.y;
    double c1 = b.x*b.x-a.x*a.x+b.y*b.y-a.y*a.y;
    double c2 = c.x*c.x-a.x*a.x+c.y*c.y-a.y*a.y;
    cir ans;
    ans.o = Point{(b2*c1-b1*c2)/(b2*a1*2-b1*a2*2),(a2*c1-a1*c2)/(a2*b1*2-a1*b2*2)};
    ans.r = dis(a,ans.o);
    return ans;
}
cir make(){
    cir ans;
    ans.o = p[1];ans.r = 0;
    for(int i =2;i<=n;i++){
        if(dis(ans.o,p[i])>ans.r+eps){
            ans.o = p[i],ans.r = 0;
            for(int  j =1;j<=i-1;j++){
                if(dis(ans.o,p[j])>ans.r+eps){
                    ans.o.x = (p[i].x+p[j].x)/2;
                    ans.o.y =(p[i].y+p[j].y)/2;
                    ans.r = dis(ans.o,p[j]);
                    for(int k = 1;k<=j-1;k++){
                        if(dis(ans.o,p[k])>ans.r+eps){
                            ans = get(p[i],p[j],p[k]);
                        }
                    }
                }
            }
        }
    }
    return ans;
}

signed main(){
    cin>>n;
    for(int i =1;i<=n;i++){
        cin>>p[i].x>>p[i].y;
    }
    random_shuffle(p.begin()+1,p.begin()+1+n);
    cir ans = make();
    printf("%.10lf %.10lf %.10lf\n",ans.o.x,ans.o.y,ans.r);

}
accuracy: 1
time_ms: 50
memory_kb: 4560
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'

const double eps = 1e-12;
struct Point{
    double x,y;
    bool operator<(Point p){
        if(x!=p.x)return x<p.x;
        return y<p.y;
    }
};
struct cir{
    Point o;
    double r;
};
vector<Point>p(100010);
int n;
double dis(Point a,Point b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
cir get(Point a,Point b,Point c){
    double a1 = b.x-a.x,a2 = c.x-a.x,b1 = b.y-a.y,b2 = c.y-a.y;
    double c1 = b.x*b.x-a.x*a.x+b.y*b.y-a.y*a.y;
    double c2 = c.x*c.x-a.x*a.x+c.y*c.y-a.y*a.y;
    cir ans;
    ans.o = Point{(b2*c1-b1*c2)/(b2*a1*2-b1*a2*2),(a2*c1-a1*c2)/(a2*b1*2-a1*b2*2)};
    ans.r = dis(a,ans.o);
    return ans;
}
cir make(){
    cir ans;
    ans.o = p[1];ans.r = 0;
    for(int i =2;i<=n;i++){
        if(dis(ans.o,p[i])>ans.r+eps){
            ans.o = p[i],ans.r = 0;
            for(int  j =1;j<=i-1;j++){
                if(dis(ans.o,p[j])>ans.r+eps){
                    ans.o.x = (p[i].x+p[j].x)/2;
                    ans.o.y =(p[i].y+p[j].y)/2;
                    ans.r = dis(ans.o,p[j]);
                    for(int k = 1;k<=j-1;k++){
                        if(dis(ans.o,p[k])>ans.r+eps){
                            ans = get(p[i],p[j],p[k]);
                        }
                    }
                }
            }
        }
    }
    return ans;
}

signed main(){
    cin>>n;
    for(int i =1;i<=n;i++){
        cin>>p[i].x>>p[i].y;
    }
    random_shuffle(p.begin()+1,p.begin()+1+n);
    cir ans = make();
    printf("%.10lf %.10lf %.10lf\n",ans.o.x,ans.o.y,ans.r);

}
accuracy: 1
time_ms: 50
memory_kb: 4568
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define fio ios_base::sync_with_stdio(0); cin.tie(0); cin.exceptions(cin.failbit);
#define int long long
#define vt vector
#define pb emplace_back
#define sz(x) (int) x.size()
#define all(x) x.begin(), x.end()
#define rep(i, from, to) for (int i = from; i <= to; ++i)
#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
// #pragma GCC target("avx,avx2,fma")
#define X first
#define Y second
#define PD pair<double, double>
const int mxn = 1000 + 5, MOD = 1e9 + 7, INF = 0x3f3f3f3f3f3f3f3f;
PD operator + (PD a, PD b) {return {a.X + b.X, a.Y + b.Y};}
PD operator - (PD a, PD b) {return {a.X - b.X, a.Y - b.Y};}
double operator ^ (PD a, PD b) {return a.X * b.Y - a.Y * b.X;}
double abs2(PD a) {return a.X * a.X + a.Y * a.Y;}
PD operator / (PD a, double b) {return {a.X / b, a.Y / b};}
int n, m;

// 外心
pair<PD, double> circumCenter (PD a, PD b, PD c) {
    b = b - a; c = c - a;
    double area4 = 2. * (b ^ c);
    PD center;
    center.X = (b.X * b.X * c.Y - c.X * c.X * b.Y + b.Y * c.Y * (b.Y - c.Y)) / area4;
    center.Y = (b.X * c.X * (c.X - b.X) - b.Y * b.Y * c.X + b.X * c.Y * c.Y) / area4;
    return {a + center, abs2(center)};
}
// 最小覆蓋圓
pair<PD, double> minimumEnclosingCircle (vt<PD> &pts) {
    // random shuffle make it O(n)
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    shuffle(all(pts), rng);
    
    PD c = pts[0];
    double r2 = 0;
    rep(i, 1, sz(pts) - 1) {
        if (abs2(pts[i] - c) <= r2) continue;
        c = pts[i]; r2 = 0;
        rep(j, 0, i - 1) {
            if (abs2(pts[j] - c) <= r2) continue;
            c = (pts[i] + pts[j]) / 2;
            r2 = abs2(pts[i] - c);
            rep(k, 0, j - 1) {
                if (abs2(pts[k] - c) > r2) {
                    tie(c, r2) = circumCenter(pts[i], pts[j], pts[k]);
                }
            }
        }
    }
    return {c, r2};
}

void solve() {
    cin >> n;
    vt<pair<double, double>> pts;
    rep(i, 1, n) {
        PD pt;
        cin >> pt.X >> pt.Y;
        pts.pb(pt);
    }
    auto [c, r2] = minimumEnclosingCircle(pts);
    cout << setprecision(10) << fixed << c.X << ' ' << c.Y << ' ' << sqrtl(r2) << '\n';
}

signed main(void){
    #ifdef AutoIO
    freopen("P:\\Code\\C\\input.txt","r",stdin);
    freopen("P:\\Code\\C\\output.txt","w",stdout);
    #endif
    fio
    int t = 1;
    // cin >> t;
    while (t--) solve();
}
accuracy: 1
time_ms: 30
memory_kb: 5256
final_rank: 5

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

namespace DBG
{
    template <class T>
    void _dbg(const char *f, T t) { cerr << f << '=' << t << '\n'; }
    template <class A, class... B>
    void _dbg(const char *f, A a, B... b)
    {
        while (*f != ',')
            cerr << *f++;
        cerr << '=' << a << ",";
        _dbg(f + 1, b...);
    }
    template <typename Container>
    void _print(const char *f, const Container &v)
    {
        cerr << f << " = [ ";
        for (const auto &x : v)
            cerr << x << ", ";
        cerr << "]\n";
    }
#define bug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define bugv(container) _print(#container, container)
}
using namespace DBG;

void _();
int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cout << fixed << setprecision(10);
    int T = 1;
    // cin >> T;
    while (T--)
        _();
    return 0;
}

#define int long long

using ld = long double;
const ld eps = 1e-9; // 9 12 15
const ld PI = acos(-1);
#define Pt Point<T>
#define Pd Point<ld>
#define Lt Line<T>
#define Ld Line<ld>

int sign(ld x) // 判符号
{
    if (fabsl(x) < eps)
        return 0;
    else
        return x < 0 ? -1 : 1;
}
bool equal(ld x, ld y) { return !sign(x - y); } // 近似
bool big(ld has, ld tar) { return sign(has - tar) > 0; }

////////////////////////////////////////////////////////////////////////////  点类

//  点与向量
template <class T>
struct Point
{
    T x, y;

    Point(T x = 0, T y = 0) : x(x), y(y) {} // 带参构造

    // 运算符重载
    Point operator+(const Point &b) const { return Point(x + b.x, y + b.y); }
    Point operator-(const Point &b) const { return Point(x - b.x, y - b.y); }
    Point operator*(T k) const { return Point(x * k, y * k); }
    Point operator/(T k) const { return Point(x / k, y / k); }

    friend bool operator<(Point a, Point b)
    {
        if (!equal(a.x, b.x))
            return a.x < b.x;
        return a.y < b.y;
    }
    friend bool operator>(Point a, Point b) { return b < a; }
    friend bool operator==(Point a, Point b) { return equal(a.x, b.x) && equal(a.y, b.y); } // 近似
    friend bool operator!=(Point a, Point b) { return !(a == b); }
    friend auto &operator>>(istream &is, Point &p) { return is >> p.x >> p.y; }
    friend auto &operator<<(ostream &os, Point p) { return os << "(" << p.x << ", " << p.y << ")"; }
};

ld len(Point<ld> a) { return sqrtl(a.x * a.x + a.y * a.y); };   // 模长
ld dis(Point<ld> a, Point<ld> b) { return len(a - b); }         // 两点距离
ld dis1(Pd a, Pd b) { return abs(a.x - b.x) + abs(a.y - b.y); } // 曼哈顿距离

ld cross(Point<ld> a, Point<ld> b) { return a.x * b.y - a.y * b.x; } // 叉积 ab*sin 两点与原点三角形面积  判两点位置关系两侧
ld cross(Point<ld> p0, Point<ld> p1, Point<ld> p2) { return cross(p1 - p0, p2 - p0); }
ld dot(Point<ld> a, Point<ld> b) { return a.x * b.x + a.y * b.y; } // 点积 ab*cos  结合判两点象限位置关系
ld dot(Point<ld> p0, Point<ld> p1, Point<ld> p2) { return dot(p1 - p0, p2 - p0); }
ld angle(Point<ld> a, Point<ld> b) { return atan2(cross(a, b), dot(a, b)); } // 向量夹角[-pi, pi]  非负fabsl
ld angle(Pd p) { return atan2l(p.y, p.x); }                                  // 极角

bool angle0(Pd a, Pd b) { return fabs(cross(a, b)) < eps && dot(a, b) > 0; } // 夹角为0
bool angle180(Pd a, Pd b) { return cross(a, b) < eps && !angle0(a, b); }     // 夹角为180

Point<ld> standardize(Point<ld> h) // 转换为单位向量
{
    ld l = len(h);
    if (sign(l) == 0)
        return {0, 0}; // 防止除零
    return h / l;
}
Pd rotate(Pd p, ld rad) { return {p.x * cos(rad) - p.y * sin(rad), p.x * sin(rad) + p.y * cos(rad)}; } // 向量旋转任意角度

Pd rotate90(Pd a) { return Point<ld>{-a.y, a.x}; }                                   // 旋转90° 垂直向量
ld toDeg(ld x) { return x * 180 / PI; }                                              // 弧度转角度
ld toArc(ld x) { return PI / 180 * x; }                                              // 角度转弧度
ld angle(ld a, ld b, ld c) { return acos((a * a + b * b - c * c) / (2.0 * a * b)); } // 余弦定理 三边求角C弧度

void psort(vector<Pd> &ps, Pd o = Pd(0, 0)) // 选定极点 极角排序 ✅
{                                           // 三四一二 [ (0, -1), (1, 0), (0, 1), (-1, 0), ]
    sort(ps.begin(), ps.end(), [&](Pd &A, Pd &B)
         { A=A-o,B=B-o;
	    auto f=[](Pd A){return A.y>0||(A.y==0&&A.x<0);};
	    if(f(A)!=f(B))return f(A)<f(B);
	    else if(cross(A,B)!=0)return cross(A,B)>0;
	    return dis(A,{0,0})<dis(B,{0,0}); });
}
////////////////////////////////////////////////////////////////////////  直线与线段

// 直线
template <class T>
struct Line
{
    Point<T> a, b;
    Line(Pt a_ = {}, Pt b_ = {}) : a(a_), b(b_) {}
    friend auto &operator<<(ostream &os, Line l) { return os << "<" << l.a << ", " << l.b << ">"; }
};
bool pointOnLineLeft(Pd p, Ld l) { return cross(l.b - l.a, p - l.a) > 0; } // 点在直线左侧 ✅
bool onLine(Pd a, Pd b, Pd c) { return sign(cross(a - b, c - b)) == 0; }   // 点是否在直线上（三点是否共线）✅
bool onLine(Pd p, Ld l) { return onLine(p, l.a, l.b); }
// 线段：点是否在线段上 ✅
bool pointOnSegment(Pd p, Ld l) { return fabsl(cross(l.a - p, l.b - p)) < eps && dot(l.a - p, l.b - p) <= 0; }
bool Parallel(Pd p1, Pd p2) { return equal(0, cross(p1, p2)); }                          // 平行 ✅
bool Orthogonal(Pd p1, Pd p2) { return equal(0, dot(p1, p2)); }                          // 垂直 ✅
Ld midSegment(Ld l) { return {(l.a + l.b) / 2, (l.a + l.b) / 2 + rotate90(l.a - l.b)}; } // 线段的中垂线

ld disPointToLine(Pd p, Ld l, bool isSegment = false) // 点到直线/线段的最近距离 ✅
{
    ld len_ab = dis(l.a, l.b);
    if (sign(len_ab) == 0)
        return dis(p, l.a);
    if (!isSegment)
    {
        ld ans = cross(p, l.a, l.b);
        return fabsl(ans) / dis(l.a, l.b); // 面积除以底边长
    }
    else
    {
        if (dot(p - l.a, l.b - l.a) <= 0)
            return dis(p, l.a);
        if (dot(p - l.b, l.a - l.b) <= 0)
            return dis(p, l.b);
        ld ans = cross(p, l.a, l.b);
        return fabsl(ans) / dis(l.a, l.b);
    }
}

Pd lineIntersection(Ld l1, Ld l2, bool seg1 = false, bool seg2 = false) // 两直线/线段相交交点 ✅
{
    ld det = cross(l1.b - l1.a, l2.b - l2.a);
    if (sign(det) == 0) // 1. 平行或共线
    {
        if (sign(cross(l2.a - l1.a, l1.b - l1.a)) != 0) // 如果不共线 -> 平行
            return Pd(1e18, 1e18);

        if (!seg1 || !seg2)
            return seg1 ? l1.a : l2.a; // 含直线的情况

        if (pointOnSegment(l1.a, l2)) // 共线情况：检查端点是否重合/相连
            return l1.a;
        if (pointOnSegment(l1.b, l2))
            return l1.b;
        if (pointOnSegment(l2.a, l1))
            return l2.a;
        if (pointOnSegment(l2.b, l1))
            return l2.b;
        return Pd(1e18, 1e18); // 完全不相交
    }

    ld t = cross(l2.a - l1.a, l2.b - l2.a) / det; // 2. 一般情况，唯一交点
    Pd inter = l1.a + (l1.b - l1.a) * t;

    if ((seg1 && !pointOnSegment(inter, l1)) || (seg2 && !pointOnSegment(inter, l2)))
        return Pd(1e18, 1e18); // 不在线段上

    return inter;
}

Pd project(Pd p, Ld l, bool isSegment = false) // 点在直线/线段上的投影点（垂足）✅
{
    Pd h = l.b - l.a;
    ld r = dot(h, p - l.a) / (h.x * h.x + h.y * h.y);
    Pd pro = l.a + h * r;
    if (isSegment)
    {
        if (dot(pro - l.a, l.b - l.a) < 0)
            return l.a;
        if (dot(pro - l.b, l.a - l.b) < 0)
            return l.b;
    }
    return pro;
}
// ////////////////////////////////////////////////////////////////////////////////////    圆

struct Circle
{
    Pd o;
    ld r;
    Circle(Pd o_ = {}, ld r_ = 0) : o(o_), r(r_) {}
};

// 外心 三角形外接圆的圆心，三角形三边垂直平分线的交点 ✅
Pd center1(Pd p1, Pd p2, Pd p3) { return lineIntersection(midSegment({p1, p2}), midSegment({p2, p3})); }
// 内心 三角形内切圆的圆心，三角形三个内角的角平分线的交点 到三角形三边的距离相等 ✅
Pd center2(Pd p1, Pd p2, Pd p3)
{
#define atan2t(p) atan2(p.y, p.x)
    Line<ld> U = {p1, {}}, V = {p2, {}};
    ld m, n, alpha;
    m = atan2t((p2 - p1));
    n = atan2t((p3 - p1));
    alpha = (m + n) / 2;
    U.b = {p1.x + cos(alpha), p1.y + sin(alpha)};
    m = atan2t((p1 - p2));
    n = atan2t((p3 - p2));
    alpha = (m + n) / 2;
    V.b = {p2.x + cos(alpha), p2.y + sin(alpha)};
    return lineIntersection(U, V);
}
// 垂心 三角形的三条高线所在直线的交点 锐角三角形的垂心在三角形内；直角三角形的垂心在直角顶点上；钝角三角形的垂心在三角形外
Pd center3(Pd p1, Pd p2, Pd p3)
{
    Ld U = {p1, p1 + rotate90(p2 - p3)}; // 垂线
    Ld V = {p2, p2 + rotate90(p1 - p3)};
    return lineIntersection(U, V);
}

tuple<int, Pd, Pd> lineCircleCross(Ld l, Pd o, ld r) // 直线是否与圆相交及交点
{                                                    // 同时返回相交状态和交点：0代表不相交；1代表相切；2代表相交
    Pd P = project(o, l);
    ld d = dis(P, o), tmp = r * r - d * d;
    if (sign(tmp) == -1)
        return {0, {}, {}};
    else if (sign(tmp) == 0)
        return {1, P, {}};
    Pd vec = standardize(l.b - l.a) * sqrt(tmp);
    return {2, P + vec, P - vec};
}
tuple<int, Pd, Pd> segmentCircleCross(Ld l, Pd o, ld r) // 线段与圆交点个数
{
    auto [type, U, V] = lineCircleCross(l, o, r);
    bool f1 = pointOnSegment(U, l), f2 = pointOnSegment(V, l);
    if (type == 1 && f1)
        return {1, U, {}};
    else if (type == 2 && f1 && f2)
        return {3, U, V};
    else if (type == 2 && f1)
        return {2, U, {}};
    else if (type == 2 && f2)
        return {2, V, {}};
    else
        return {0, {}, {}};
}

// 两圆是否相交及交点 同时返回相交状态和交点： 0-内含, 1-相离, 2-相切, 3-相交{1交点时判内切外切} ✅
tuple<int, Pd, Pd> circleIntersection(Circle c1, Circle c2)
{
    Pd p1 = c1.o;
    ld r1 = c1.r;
    Pd p2 = c2.o;
    ld r2 = c2.r;
    ld d = dis(p1, p2);
    if (sign(d) == 0)
        return {(equal(r1, r2) ? -1 : 0), {}, {}}; // 重合 or 不交
    if (sign(r1 + r2 - d) < 0)
        return {1, {}, {}}; // 外离
    if (sign(fabsl(r1 - r2) - d) > 0)
        return {0, {}, {}}; // 内含
    ld x = (d * d + r1 * r1 - r2 * r2) / (2 * d);
    ld y = sqrtl(max((ld)0, r1 * r1 - x * x));
    Pd mid = p1 + (p2 - p1) * (x / d);
    Pd pA = mid + rotate(standardize(p2 - p1), PI / 2) * y;
    Pd pB = mid - rotate(standardize(p2 - p1), PI / 2) * y;
    if (pA == pB)
        return {2, pA, pA};
    return {3, pA, pB};
}

// 根据圆心角获取圆上某点  将圆上最右侧的点以圆心为旋转中心，逆时针旋转 rad 度
Point<ld> getPoint(Point<ld> p, ld r, ld rad) { return {p.x + cos(rad) * r, p.y + sin(rad) * r}; }

int tangentCnt(Circle c1, Circle c2) // 公切线数量 两圆位置关系 ✅
{                                    // 0内含 1内接 2相交 3相切 4相离
    if (c1.r < c2.r)
        swap(c1, c2);
    ld d = len(c1.o - c2.o);
    ld r = c1.r + c2.r;
    if (equal(d, r))
        return 3;
    if (d > r)
        return 4;
    if (equal(d + c2.r, c1.r))
        return 1;
    if (d + c2.r < c1.r)
        return 0;
    return 2;
}

ld disEx(Pd a, Pd b) { return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y); } // dis无开根版

pair<int, vector<Point<ld>>> tangent(Point<ld> p, Circle c) // 点到圆的切线数量与切点 ✅
{
    Point<ld> A = c.o;
    ld r = c.r;
    vector<Point<ld>> ans;
    Point<ld> u = p - A;
    ld d = len(u);
    if (d < r - eps)
        return {0, {}}; // 点在圆内，无切线

    else if (sign(d - r) == 0)
    {
        ans.push_back(p); // 点在圆上，切点就是自己
        return {1, ans};
    }
    else // 点在圆外，有两条切线
    {
        u = u / d; // 单位向量
        Pd v = rotate90(u);
        ld h = sqrt(d * d - r * r);
        ans.push_back(A + u * (r * r / d) + v * (r * h / d));
        ans.push_back(A + u * (r * r / d) - v * (r * h / d));
        return {2, ans};
    }
}

// 同时返回两圆公切线数量以及每个圆的切点。 ✅
tuple<int, vector<Point<ld>>, vector<Point<ld>>> tangent(Circle c1, Circle c2)
{
    Point<ld> A = c1.o;
    ld Ar = c1.r;
    Point<ld> B = c2.o;
    ld Br = c2.r;
    vector<Point<ld>> a, b;

    bool swapped = false;
    if (Ar < Br)
        swap(Ar, Br), swap(A, B), swapped = true;

    ld d2 = disEx(B, A); // 平方距离
    ld dif = Ar - Br, sum = Ar + Br;
    if (d2 < dif * dif)
        return {0, {}, {}}; // 内含
    ld base = atan2(B.y - A.y, B.x - A.x);
    if (d2 == 0 && Ar == Br)
        return {-1, {}, {}}; // 重合
    if (d2 == dif * dif)
    { // 内切
        a.push_back(getPoint(A, Ar, base));
        b.push_back(getPoint(B, Br, base));
        if (swapped)
            return {1, b, a};
        else
            return {1, a, b};
    }
    ld d = sqrt(d2);
    ld ang = acos(dif / d);
    a.push_back(getPoint(A, Ar, base + ang));
    a.push_back(getPoint(A, Ar, base - ang));
    b.push_back(getPoint(B, Br, base + ang));
    b.push_back(getPoint(B, Br, base - ang));

    if (d2 == sum * sum) // 外切
    {
        a.push_back(getPoint(A, Ar, base));
        b.push_back(getPoint(B, Br, base + PI));
    }
    else if (d2 > sum * sum) // 相离
    {
        ang = acos(sum / d);
        a.push_back(getPoint(A, Ar, base + ang));
        a.push_back(getPoint(A, Ar, base - ang));
        b.push_back(getPoint(B, Br, base + ang + PI));
        b.push_back(getPoint(B, Br, base - ang + PI));
    }

    if (swapped)
        return {(int)a.size(), b, a};
    else
        return {(int)a.size(), a, b};
}

// 两圆相交面积 ✅
ld circleIntersectionArea(Circle c1, Circle c2)
{
    Pd p1 = c1.o;
    ld r1 = c1.r;
    Pd p2 = c2.o;
    ld r2 = c2.r;
    ld d = dis(p1, p2);
    if (sign(fabsl(r1 - r2) - d) >= 0) // 一圆包含另一圆
        return PI * min(r1 * r1, r2 * r2);
    if (sign(r1 + r2 - d) <= 0) // 两圆相离
        return 0;

    ld theta1 = angle(r1, d, r2);
    ld theta2 = angle(r2, d, r1);
    ld area1 = r1 * r1 * (theta1 - sin(2 * theta1) / 2);
    ld area2 = r2 * r2 * (theta2 - sin(2 * theta2) / 2);
    return area1 + area2;
}

// 点到圆的最近点
// 返回 {圆上最近点, 距离}
// pair<Pd, ld> pointToCircle(Pd p, Pd o, ld r) {
//     if (r < 0) { // 非法半径
//         return {o, -1};
//     }
//     Pd v = p - o;
//     ld d = len(v);
//     if (sign(d) == 0) {
//         // p 就是圆心，任意取圆上点
//         Pd nearest = {o.x + r, o.y};
//         return {nearest, r};
//     }
//     Pd nearest = o + v * (r / max(d, eps)); // 防止除0
//     return {nearest, dis(p, nearest)};
// }

// 三点确定一圆
// 返回 (状态, 圆)
// 状态：0:不存在(三点共线或重合)  1:唯一圆
pair<int, Circle> getCircle(Pd A, Pd B, Pd C)
{
    if (sign(len(A - B)) == 0 || sign(len(A - C)) == 0 || sign(len(B - C)) == 0)
        return {0, {}};                 // 排除退化情况：点重合
    if (sign(cross(B - A, C - A)) == 0) // 排除三点共线
        return {0, {}};

    Pd o = center1(A, B, C);
    ld r = dis(A, o);
    return {1, Circle(o, r)};
}
Circle minCircle(vector<Pd> &p) // 最小圆覆盖
{
    random_shuffle(p.begin(), p.end()); // 随机打乱
    Circle c = {p[0], 0};
    int n = p.size();
    for (int i = 1; i < n; i++)
        if (c.r < dis(c.o, p[i]))
        {
            c = {p[i], 0};
            for (int j = 0; j < i; j++)
                if (c.r < dis(c.o, p[j]))
                {
                    c = {(p[i] + p[j]) / 2, dis(p[i], p[j]) / 2};
                    for (int k = 0; k < j; k++)
                        if (c.r < dis(c.o, p[k]))
                            c = getCircle(p[i], p[j], p[k]).second;
                }
        }
    return c;
}

void _()
{
    int n;
    cin >> n;
    vector<Pd> p(n);
    for (auto &v : p)
        cin >> v;

    auto C = minCircle(p);

    // cout << C.r << ' ';
    cout << C.o.x << ' ' << C.o.y << ' ' << C.r << '\n';
}
accuracy: 1
time_ms: 30
memory_kb: 6236
final_rank: 7

code_snippet: #include<bits/stdc++.h>
#define siz(x) int((x).size())
#define all(x) std::begin(x),std::end(x)
#define fi first
#define se second
using namespace std;
using unt=unsigned;
using loli=long long;
using lolu=unsigned long long;
using pii=pair<int,int>;
mt19937_64 rng(random_device{}());
constexpr double eps=1e-8;
template<typename any>inline any sqr(const any &x){return x*x;}
inline int get_op(double x){if(fabs(x)<eps)return 0;return x>0?1:-1;}
double det(array<double,3>a0,array<double,3>a1,array<double,3>a2){
	double sum=0;
	sum+=a0[0]*a1[1]*a2[2];
	sum+=a1[0]*a2[1]*a0[2];
	sum+=a2[0]*a0[1]*a1[2];
	sum-=a0[2]*a1[1]*a2[0];
	sum-=a0[1]*a1[0]*a2[2];
	sum-=a0[0]*a1[2]*a2[1];
	return sum;
}
struct bector{
	double x,y;
	bool operator<(const bector&t)const{return fabs(x-t.x)<eps?y<t.y:x<t.x;}
	bool operator==(const bector&t)const{return fabs(x-t.x)<eps&&fabs(y-t.y)<eps;}
	bector(double a=0,double b=0):x(a),y(b){}
	double operator~()const{return sqrt(x*x+y*y);}
	double operator*()const{return x*x+y*y;}
	friend istream&operator>>(istream&a,bector&b){return a>>b.x>>b.y;}
	friend ostream&operator<<(ostream&a,const bector&b){return a<<b.x<<' '<<b.y;}
	friend bector operator+(const bector&a,const bector&b){return {a.x+b.x,a.y+b.y};}
	bector&operator+=(const bector&t){x+=t.x,y+=t.y;return *this;}
	friend bector operator-(const bector&a,const bector&b){return {a.x-b.x,a.y-b.y};}
	bector&operator-=(const bector&t){x-=t.x,y-=t.y;return *this;}
	friend bector operator*(const bector&a,double b){return {a.x*b,a.y*b};}
	friend bector operator*(double b,const bector&a){return {a.x*b,a.y*b};}
	bector&operator*=(double t){x*=t,y*=t;return *this;}
	friend bector operator/(const bector&a,double b){return {a.x/b,a.y/b};}
	bector&operator/=(double t){x/=t,y/=t;return *this;}
	friend double operator*(const bector&a,const bector&b){return a.x*b.x+a.y*b.y;}
	friend double operator/(const bector&a,const bector&b){return a.x*b.y-a.y*b.x;}
	bool frontis(const bector&t)const{auto r=*this*t;return get_op(r)>0;}
	bool backis(const bector&t)const{auto r=*this*t;return get_op(r)<0;}
	bool leftis(const bector&t)const{auto r=*this/t;return get_op(r)>0;}
	bool rightis(const bector&t)const{auto r=*this/t;return get_op(r)<0;}
	bool front1s(const bector&t)const{auto r=*this*t;return get_op(r)>=0;}
	bool back1s(const bector&t)const{auto r=*this*t;return get_op(r)<=0;}
	bool left1s(const bector&t)const{auto r=*this/t;return get_op(r)>=0;}
	bool right1s(const bector&t)const{auto r=*this/t;return get_op(r)<=0;}
	friend double dis(const bector&a,const bector&b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
	bector rot90()const{return {-y,x};}
	double arg()const{return atan2(y,x);}
	bector rotate(const bector&a,double r){
		auto u=a-*this;
		return *this+bector{u.x*cos(r)-u.y*sin(r),u.x*sin(r)+u.y*cos(r)};
	}
	friend double c0s(const bector&x,const bector&y){
		// 求 cos<x,y>
		return x*y/~x/~y;
	}
	bector unit()const{
		return (*this)/~(*this);
	}
	friend bool operator&(const bector&a,const bector&b){return !get_op(a*b);}
	friend bool operator|(const bector&a,const bector&b){return !get_op(a/b);}
	friend double triarea(const bector&x,const bector&y,const bector&z){
		return (y-x)/(z-x)/2;
	}
};
bector polar(double p,double r){return {cos(r)*p,sin(r)*p};}
struct segment{
	bector p1,p2;
	segment(const bector&a={0,0},const bector&b={0,0}):p1(a),p2(b){};
	friend istream&operator>>(istream&a,segment &b){return a>>b.p1>>b.p2;}
	friend ostream&operator<<(ostream&a,const segment&b){return a<<b.p1<<' '<<b.p2;}
	friend bool operator&(const segment&a,const segment&b){return !get_op((a.p2-a.p1)*(b.p2-b.p1));}
	friend bool operator|(const segment&a,const segment&b){return !get_op((a.p2-a.p1)/(b.p2-b.p1));}
	bool leftis(const bector&t)const{return (p2-p1).leftis(t-p1);}
	bool rightis(const bector&t)const{return (p2-p1).rightis(t-p1);}
	bool left1s(const bector&t)const{return (p2-p1).left1s(t-p1);}
	bool right1s(const bector&t)const{return (p2-p1).right1s(t-p1);}
	bool check(const bector&t)const{
		// cerr<<left1s(t)<<' '<<right1s(t)<<'\n';
		return left1s(t)&&right1s(t);
	}
	// bool check(const bector&t)const{return left1s(t)&&right1s(t);}
	friend bool banana(const segment&a,const segment&b){
		// 判断是否相交
		if(min(a.p1.x,a.p2.x)>max(b.p1.x,b.p2.x)||min(b.p1.x,b.p2.x)>max(a.p1.x,a.p2.x)||min(a.p1.y,a.p2.y)>max(b.p1.y,b.p2.y)||min(b.p1.y,b.p2.y)>max(a.p1.y,a.p2.y))return false;
		return get_op(((a.p2-a.p1)/(b.p1-a.p1))*((a.p2-a.p1)/(b.p2-a.p1)))<=0&&get_op(((b.p2-b.p1)/(a.p1-b.p1))*((b.p2-b.p1)/(a.p2-b.p1)))<=0;
	}
	friend bector focus(const segment&a,const segment&b){
		// 输入必须保证有交，输出交点
		bector v=a.p2-a.p1,w=b.p2-b.p1,u=a.p1-b.p1;
		return a.p1+v*((w/u)/(v/w));
	}
	friend double dis(const segment&a,const bector&b){
		if(a.p1==a.p2)return ~(b-a.p1);
		auto v1=a.p2-a.p1,v2=b-a.p1,v3=b-a.p2;
		if(v1.backis(v2))return ~v2;
		if(v1.frontis(v3))return ~v3;
		return fabs(v1/v2)/~v1;
	}
	friend double dis(const segment&a,const segment&b){
		// 求线段间最短距离
		if(banana(a,b))return 0;
		return min({dis(a,b.p1),dis(a,b.p2),dis(b,a.p1),dis(b,a.p2)});
	}
	bector project(const bector&a)const{
		// 求点 a 在当前线段上的投影点坐标
		if(a==p1||a==p2)return a;
		auto u=p2-p1,v=a-p1;
		return c0s(u,v)*(~v)*u.unit()+p1;
	}
	double pr0ject(const bector&a)const{
		return dis(a,project(a));
	}
	bector reflect(const bector&a)const{
		// 求点 a 在当前线段上的对称点
		return 2*project(a)-a;
	}
	segment&sort(){if(p2<p1)std::swap(p1,p2);return *this;}
};
struct circle{
	bector p;double r;
	circle(const bector&a={0,0},double b=0):p(a),r(b){}
	circle(bector p1,bector p2){
		p=(p1+p2)/2;
		r=dis(p1,p2)/2;
	}
	circle(bector p1,bector p2,bector p3){
		p.x=det({*p1,p1.y,1},{*p2,p2.y,1},{*p3,p3.y,1})/2/det({p1.x,p1.y,1},{p2.x,p2.y,1},{p3.x,p3.y,1});
		p.y=-det({*p1,p1.x,1},{*p2,p2.x,1},{*p3,p3.x,1})/2/det({p1.x,p1.y,1},{p2.x,p2.y,1},{p3.x,p3.y,1});
		r=dis(p,p1);
	}
	friend istream&operator>>(istream&a,circle &b){return a>>b.p>>b.r;}
	friend ostream&operator<<(ostream&a,const circle &b){return a<<b.p<<' '<<b.r;}
	bool check(bector t){
		return dis(p,t)-r<=eps;
	}
	friend segment focus(const circle &a,const segment&b){
		auto d=b.project(a.p),u=b.p2-b.p1,e=u/~u;
		auto t=sqrt(a.r*a.r-sqr(dis(d,a.p)));
		return segment{d+e*t,d-e*t}.sort();
	}
	friend segment focus(const circle &a,const circle &b){
		auto d=dis(a.p,b.p),l=acos((sqr(a.r)+sqr(d)-sqr(b.r))/(2*a.r*d)),t=(b.p-a.p).arg();
		return segment{a.p+polar(a.r,t+l),a.p+polar(a.r,t-l)}.sort();
	}
	segment tangent(const bector&a){
		auto u=a-p;
		auto l=acos(r/~u);
		u=u*r/~u;
		return segment{p.rotate(p+u,+l),p.rotate(p+u,-l)}.sort();
	}
};
struct points:vector<bector>{
#define p (*this)
	points&read(istream&t,int n=-1){
		if(n==-1)cin>>n;
		p.resize(n);
		for(int i=0;i<n;i++)t>>p[i];
		return *this;
	}
	double area()const{
		// 无需满足多边形是凸的
		double ans=0;
		for(int i=1;i<siz(p)-1;i++)ans+=(p[i]-p[0])/(p[i+1]-p[0]);
		return ans/2;
	}
	points tobag(){
		sort(all(p));
		erase(unique(all(p)),end());
		points b;
		for(int i=0;i<siz(p);i++){
			while(siz(b)>1&&get_op((b.back()-b[siz(b)-2])/(p[i]-b[siz(b)-2]))<=0)
			// while(siz(b)>1&&get_op((b.back()-b[siz(b)-2])/(p[i]-b[siz(b)-2]))<0)
				b.pop_back();
			b.push_back(p[i]);
		}
		int o=siz(b);
		for(int i=siz(p)-2;~i;i--){
			while(siz(b)>o&&get_op((b.back()-b[siz(b)-2])/(p[i]-b[siz(b)-2]))<=0)
			// while(siz(b)>o&&get_op((b.back()-b[siz(b)-2])/(p[i]-b[siz(b)-2]))<0)
				b.pop_back();
			b.push_back(p[i]);
		}
		// if(siz(p)>1)b.pop_back();
		return b;
	}
	double xzqk()const{
		if(siz(p)==1)return 0;
		if(siz(p)==2)return dis(p[0],p[1]);
		if(siz(p)==3)return max({dis(p[0],p[1]),dis(p[0],p[2]),dis(p[1],p[2])});
		double ans=0;
		for(int i=1,j=2;i<siz(p);i++){
			while(get_op(triarea(p[i-1],p[i],p[j])-triarea(p[i-1],p[i],p[(j+1)%siz(p)]))<=0)
				(++j)%=siz(p);
			ans=max({ans,dis(p[i-1],p[j]),dis(p[i],p[j])});
		}
		return ans;
	}
	double kqzx(){
		sort(all(p));
		auto solve=[&](auto&&self,int l,int r){
			if(l==r)return 1e18;
			int mid=(l+r)/2;
			double ans=min(self(self,l,mid),self(self,mid+1,r));
			points b;
			for(int i=l;i<=r;i++)if(fabs(p[mid].x-p[i].x)<=ans)b.push_back(p[i]);
			sort(all(b),[](const bector&x,const bector&y){
				if(x.y==y.y)return x.x<y.x;
				return x.y<y.y;
			});
			for(int i=0;i<siz(b);i++)for(int j=i+1;j<siz(b);j++){
				if(b[j].y-b[i].y>=ans)break;
				ans=min(ans,dis(b[i],b[j]));
			}
			return ans;
		};
		return solve(solve,0,siz(p)-1);
	}
	circle incircle(){
		assert(siz(p)==3);
		auto u=p[1]-p[0],v=p[2]-p[0];u=u/~u*~v;
		segment l1{p[0],p[0]+u+v};
		u=p[2]-p[1],v=p[0]-p[1];u=u/~u*~v;
		segment l2{p[1],p[1]+u+v};
		auto pp=focus(l1,l2);
		return circle{pp,dis(segment{p[0],p[1]},pp)};
	}
	circle outcirce(){
		assert(siz(p)==3);
		auto u=p[1]-p[0],mid=(p[0]+p[1])/2;
		segment l1{mid,mid+u.rot90()};
		u=p[2]-p[0],mid=(p[0]+p[2])/2;
		segment l2{mid,mid+u.rot90()};
		auto pp=focus(l1,l2);
		return circle{pp,dis(p[0],pp)};
	}
	int contains(bector t){
		// 无需满足多边形是凸的
		// 2表示包含，1表示在边上，0表示在外面
		bool res=false;
		for(int i=0;i<siz(p);i++){
			auto a=p[i]-t,b=p[(i+1)%siz(p)]-t;
			if(!a.leftis(b)&&!a.rightis(b)&&!a.frontis(b))return 1;
			if(a.y>b.y)std::swap(a,b);
			if(a.y<eps&&eps<b.y&&a.leftis(b))res=!res;
		}
		return res?2:0;
	}
	points leftpoints(const segment&l)const{
		points b;
		// cerr<<"check "<<l<<'\n';
		for(int i=0;i<siz(p);i++){
			if(l.check(p[i]))b.push_back(p[i]);
			else if(l.rightis(p[(i-1+siz(p))%siz(p)])&&l.leftis(p[i])&&l.rightis(p[(i+1)%siz(p)])){
				b.push_back(focus(l,segment(p[i],p[(i-1+siz(p))%siz(p)])));
				b.push_back(p[i]);
				b.push_back(focus(l,segment(p[i],p[(i+1)%siz(p)])));
			}else if(l.leftis(p[i])&&l.rightis(p[(i+1)%siz(p)])){
				b.push_back(p[i]);
				b.push_back(focus(l,segment(p[i],p[(i+1)%siz(p)])));
			}else if(l.leftis(p[i])&&l.rightis(p[(i-1+siz(p))%siz(p)])){
				b.push_back(focus(l,segment(p[i],p[(i-1+siz(p))%siz(p)])));
				b.push_back(p[i]);
			}else if(l.leftis(p[i]))b.push_back(p[i]);
		}
		return b;
	}
	circle mingenshin(){
		shuffle(all(p),rng);
		circle ans;
		for(int i=0;i<siz(p);i++)if(!ans.check(p[i])){
			ans={p[i],0};
			for(int j=0;j<i;j++)if(!ans.check(p[j])){
				ans=circle(p[i],p[j]);
				for(int k=0;k<j;k++)if(!ans.check(p[k])){
					ans=circle(p[i],p[j],p[k]);
				}
			}
		}
		return ans;
	}
#undef p
};
signed main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	std::ios::sync_with_stdio(false);cin.tie(nullptr);
	cout<<setiosflags(ios::fixed)<<setprecision(10);
	points a;
	a.read(cin);
	circle o=a.mingenshin();
	cout<<o.p<<' '<<o.r<<'\n';
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 4672
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pll = pair<ll, ll>;
using vl = vector<ll>;
template <class T> using vec = vector<T>;
template <class T> using vv = vec<vec<T>>;
template <class T> using vvv = vv<vec<T>>;
template <class T> using minpq = priority_queue<T, vector<T>, greater<T>>;
#define rep(i, r) for(ll i = 0; i < (r); i++)
#define reps(i, l, r) for(ll i = (l); i < (r); i++)
#define rrep(i, l, r) for(ll i = (r) - 1; i >= l; i--)
template <class T> void uniq(T &a) { sort(all(a)); erase(unique(all(a)), a.end()); }
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)(a).size()
const ll INF = numeric_limits<ll>::max() / 4;
const ld inf = numeric_limits<ld>::max() / 2;
const ll mod1 = 1000000007;
const ll mod2 = 998244353;
const ld pi = 3.141592653589793238;
template <class T> void rev(T &a) { reverse(all(a)); }
ll popcnt(ll a) { return __builtin_popcountll(a); }
template<typename T>
bool chmax(T &a, const T& b) { return a < b ? a = b, true : false; }
template<typename T>
bool chmin(T &a, const T& b) { return a > b ? a = b, true : false; }
const ll mod = mod1;
struct mint {
	ll x;
	mint(ll y = 0) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
	mint &operator+=(const mint &p) {
		if ((x += p.x) >= mod) x -= mod;
		return *this;
	}
	mint &operator-=(const mint &p) {
		if ((x += mod - p.x) >= mod) x -= mod;
		return *this;
	}
	mint &operator*=(const mint &p) {
		x = (ll)(1ll * x * p.x % mod);
		return *this;
	}
	mint &operator/=(const mint &p) {
		*this *= p.inv();
		return *this;
	}
	mint operator-() const { return mint(-x); }
	mint operator+(const mint &p) const { return mint(*this) += p; }
	mint operator-(const mint &p) const { return mint(*this) -= p; }
	mint operator*(const mint &p) const { return mint(*this) *= p; }
	mint operator/(const mint &p) const { return mint(*this) /= p; }
	bool operator==(const mint &p) const { return x == p.x; }
	bool operator!=(const mint &p) const { return x != p.x; }
	friend ostream &operator<<(ostream &os, const mint &p) { return os << p.x; }
	friend istream &operator>>(istream &is, mint &a) {
		ll t; is >> t; a = mint(t); return (is);
	}
	mint inv() const { return pow(mod - 2); }
	mint pow(ll n) const {
		mint ret(1), mul(x);
		while (n > 0) {
			if (n & 1) ret *= mul;
			mul *= mul;
			n >>= 1;
		}
		return ret;
	}
};
void YesNo(bool t) {
	cout << (t ? "Yes" : "No") << endl;
}
#define EPS (1e-10)
#define eq(a, b) (fabs((a) - (b)) < EPS)
ll sign(ld x) { return (x >= EPS) - (x <= -EPS); }
class Point {
	typedef Point P;
public:
	ld x, y;

	Point(ld _x = 0, ld _y = 0) : x(_x), y(_y) {}

	P operator+(Point p) const { return P(x + p.x, y + p.y); }
	P operator-(Point p) const { return P(x - p.x, y - p.y); }
	P operator*(ld a) const { return P(a * x, a * y); }
	P operator/(ld a) const { return P(x / a, y / a); }

	ld abs() const { return sqrtl(norm()); }
	ld norm() const { return x * x + y * y; }

	bool operator<(const P& p) const { return tie(x, y) < tie(p.x, p.y); }
	bool operator==(const P& p) const { return eq(x, p.x) && eq(y, p.y); }
	ld dot(P p) const { return x * p.x + y * p.y; }
	ld cross(P p) const { return x * p.y - y * p.x; }
	ld cross(P a, P b) const { return (a-*this).cross(b-*this); }
	ld angle() const { return atan2(y, x); }
	P unit() const { return *this / abs(); }
	P perp() const { return P(-y, x); }
	P normal() const { return perp()/abs(); }
	P rotate(ld theta) const {
		return P(x*cosl(theta)-y*sinl(theta), x*sinl(theta)+y*cosl(theta));
	}
	P rotate(ld theta, Point &p) const {
		return (*this - p).rotate(theta) + p;
	}
};
typedef Point Vector;
struct Segment {
	Point s;
	Point e;
};
typedef Segment Line;
class Circle {
public:
	Point c;
	ld r;
	Circle(Point c = Point(), ld r = 0.0) : c(c), r(r) {}
};
typedef vector<Point> Polygon;
pair<bool, Point> lineInter(Line l1, Line l2) {
	auto d = (l1.e - l1.s).cross(l2.e - l2.s);
	if (sign(d) == 0) return { -eq(l1.s.cross(l1.e, l2.s), (ld)0), Point(0, 0) };
	auto p = l2.s.cross(l1.e, l2.e), q = l2.s.cross(l2.e, l1.s);
	return {1, (l1.s * p + l1.e * q) / d};
}
Polygon polygonCut(Polygon &p, Point s, Point e) {
	Polygon res;
	rep(i, sz(p)) {
		Point cur = p[i], prev = i ? p[i - 1] : p.back();
		bool side = sign(s.cross(e, cur)) < 0;
		if (side != (sign(s.cross(e, prev)) < 0)) {
			res.push_back(lineInter({s, e}, {cur, prev}).second);
		}
		if (side) res.push_back(cur);
	}
	return res;
}
ld Area(Polygon S) {
	ld ans = 0;
	rep(i, sz(S) - 2) {
		ans += (S[i + 1] - S[0]).cross(S[i + 2] - S[0]) * 0.5;
	}
	return ans;
}
Circle ccCicle(Point &A, Point &B, Point &C) {
	Point b = C - A, c = B - A;
	Point center = A + (b * c.norm() - c * b.norm()).perp() / b.cross(c) / 2;
	ld radius = (B - A).abs() * (C - B).abs() * (A - C).abs() / fabs((B - A).cross(C - A)) / 2;
	return Circle(center, radius);
}
Circle mec(Polygon ps) {
	shuffle(all(ps), mt19937(time(0)));
	Circle c = {ps[0], 0};
	ld eps = 1 + 1e-10;
	rep(i, sz(ps)) if ((c.c - ps[i]).abs() >  c.r * eps) {
		c.c = ps[i], c.r = 0;
		rep(j, i) if ((c.c - ps[j]).abs() > c.r * eps) {
			c.c = (ps[i] + ps[j]) / 2;
			c.r = (c.c - ps[i]).abs();
			rep(k, j) if ((c.c - ps[k]).abs() > c.r * eps) {
				c = ccCicle(ps[i], ps[j], ps[k]);
			}
		}
	}
	return c;
}
void solve() {
	ll n; cin >> n;
	Polygon g(n);
	rep(i, n) cin >> g[i].x >> g[i].y;
	Circle ans = mec(g);
	cout << fixed << setprecision(12) << ans.c.x << ' ' << ans.c.y << ' ' << ans.r << endl;
}
int main() {
	ll T = 1;
	// cin >> T;
	while (T--) solve();
}
accuracy: 1
time_ms: 50
memory_kb: 9416
final_rank: 15

code_snippet: #ifndef HIDDEN_IN_VS // 折りたたみ用

// 警告の抑制
#define _CRT_SECURE_NO_WARNINGS

// ライブラリの読み込み
#include <bits/stdc++.h>
using namespace std;

// 型名の短縮
using ll = long long; using ull = unsigned long long; // -2^63 ～ 2^63 = 9e18（int は -2^31 ～ 2^31 = 2e9）
using pii = pair<int, int>;	using pll = pair<ll, ll>;	using pil = pair<int, ll>;	using pli = pair<ll, int>;
using vi = vector<int>;		using vvi = vector<vi>;		using vvvi = vector<vvi>;	using vvvvi = vector<vvvi>;
using vl = vector<ll>;		using vvl = vector<vl>;		using vvvl = vector<vvl>;	using vvvvl = vector<vvvl>;
using vb = vector<bool>;	using vvb = vector<vb>;		using vvvb = vector<vvb>;
using vc = vector<char>;	using vvc = vector<vc>;		using vvvc = vector<vvc>;
using vd = vector<double>;	using vvd = vector<vd>;		using vvvd = vector<vvd>;
template <class T> using priority_queue_rev = priority_queue<T, vector<T>, greater<T>>;
using Graph = vvi;

// 定数の定義
const double PI = acos(-1);
int DX[4] = { 1, 0, -1, 0 }; // 4 近傍（下，右，上，左）
int DY[4] = { 0, 1, 0, -1 };
int INF = 1001001001; ll INFL = 4004004003094073385LL; // (int)INFL = INF, (int)(-INFL) = -INF;

// 入出力高速化
struct fast_io { fast_io() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(18); } } fastIOtmp;

// 汎用マクロの定義
#define all(a) (a).begin(), (a).end()
#define sz(x) ((int)(x).size())
#define lbpos(a, x) (int)distance((a).begin(), std::lower_bound(all(a), (x)))
#define ubpos(a, x) (int)distance((a).begin(), std::upper_bound(all(a), (x)))
#define Yes(b) {cout << ((b) ? "Yes\n" : "No\n");}
#define rep(i, n) for(int i = 0, i##_len = int(n); i < i##_len; ++i) // 0 から n-1 まで昇順
#define repi(i, s, t) for(int i = int(s), i##_end = int(t); i <= i##_end; ++i) // s から t まで昇順
#define repir(i, s, t) for(int i = int(s), i##_end = int(t); i >= i##_end; --i) // s から t まで降順
#define repe(v, a) for(const auto& v : (a)) // a の全要素（変更不可能）
#define repea(v, a) for(auto& v : (a)) // a の全要素（変更可能）
#define repb(set, d) for(int set = 0, set##_ub = 1 << int(d); set < set##_ub; ++set) // d ビット全探索（昇順）
#define repis(i, set) for(int i = lsb(set), bset##i = set; i < 32; bset##i -= 1 << i, i = lsb(bset##i)) // set の全要素（昇順）
#define repp(a) sort(all(a)); for(bool a##_perm = true; a##_perm; a##_perm = next_permutation(all(a))) // a の順列全て（昇順）
#define uniq(a) {sort(all(a)); (a).erase(unique(all(a)), (a).end());} // 重複除去
#define EXIT(a) {cout << (a) << endl; exit(0);} // 強制終了
#define inQ(x, y, u, l, d, r) ((u) <= (x) && (l) <= (y) && (x) < (d) && (y) < (r)) // 半開矩形内判定

// 汎用関数の定義
template <class T> inline ll powi(T n, int k) { ll v = 1; rep(i, k) v *= n; return v; }
template <class T> inline bool chmax(T& M, const T& x) { if (M < x) { M = x; return true; } return false; } // 最大値を更新（更新されたら true を返す）
template <class T> inline bool chmin(T& m, const T& x) { if (m > x) { m = x; return true; } return false; } // 最小値を更新（更新されたら true を返す）
template <class T> inline T getb(T set, int i) { return (set >> i) & T(1); }
template <class T> inline T smod(T n, T m) { n %= m; if (n < 0) n += m; return n; } // 非負mod

// 演算子オーバーロード
template <class T, class U> inline istream& operator>>(istream& is, pair<T, U>& p) { is >> p.first >> p.second; return is; }
template <class T> inline istream& operator>>(istream& is, vector<T>& v) { repea(x, v) is >> x; return is; }
template <class T> inline vector<T>& operator--(vector<T>& v) { repea(x, v) --x; return v; }
template <class T> inline vector<T>& operator++(vector<T>& v) { repea(x, v) ++x; return v; }

#endif // 折りたたみ用


#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;

#ifdef _MSC_VER
#include "localACL.hpp"
#endif

using mint = modint998244353;
//using mint = static_modint<(int)1e9+7>;
//using mint = modint; // mint::set_mod(m);

using vm = vector<mint>; using vvm = vector<vm>; using vvvm = vector<vvm>; using vvvvm = vector<vvvm>; using pim = pair<int, mint>;
#endif


#ifdef _MSC_VER // 手元環境（Visual Studio）
#include "local.hpp"
#else // 提出用（gcc）
int mute_dump = 0;
int frac_print = 0;
#if __has_include(<atcoder/all>)
namespace atcoder {
	inline istream& operator>>(istream& is, mint& x) { ll x_; is >> x_; x = x_; return is; }
	inline ostream& operator<<(ostream& os, const mint& x) { os << x.val(); return os; }
}
#endif
inline int popcount(int n) { return __builtin_popcount(n); }
inline int popcount(ll n) { return __builtin_popcountll(n); }
inline int lsb(int n) { return n != 0 ? __builtin_ctz(n) : 32; }
inline int lsb(ll n) { return n != 0 ? __builtin_ctzll(n) : 64; }
inline int msb(int n) { return n != 0 ? (31 - __builtin_clz(n)) : -1; }
inline int msb(ll n) { return n != 0 ? (63 - __builtin_clzll(n)) : -1; }
#define dump(...)
#define dumpel(v)
#define dump_math(v)
#define input_from_file(f)
#define output_to_file(f)
#define Assert(b) { if (!(b)) { vc MLE(1<<30); EXIT(MLE.back()); } } // RE の代わりに MLE を出す
#endif


//【平面上の点，二次元ベクトル】
/*
* 平面における点／二次元ベクトルを表す構造体
*
* Point<T>() : O(1)
*	(0, 0) で初期化する．
*
* Point<T>(T x, T y) : O(1)
*	(x, y) で初期化する．
*
* p1 == p2, p1 != p2, p1 < p2, p1 > p2, p1 <= p2, p1 >= p2 : O(1)
*	x 座標優先，次いで y 座標の大小比較を行う．
*
* p1 + p2, p1 - p2, c * p, p * c, p / c : O(1)
*	ベクトルとみなした加算，減算，スカラー倍，スカラー除算を行う．複合代入演算子も使用可．
*
* T sqnorm() : O(1)
*	自身の 2 乗ノルムを返す．
*
* double norm() : O(1)
*	自身のノルムを返す．
*
* Point<double> normalize() : O(1)
*	自身を正規化したベクトルを返す．
*
* T dot(Point<T> p) : O(1)
*	自身と p との内積を返す．
*
* T cross(Point<T> p) : O(1)
*	自身と p との外積を返す．
*
* double angle(Point<T> p) : O(1)
*	自身から p までの成す角度を返す．
*/
template <class T>
struct Point {
	// 点の x 座標，y 座標
	T x, y;

	// コンストラクタ
	Point() : x(0), y(0) {}
	Point(T x_, T y_) : x(x_), y(y_) {}

	// 代入
	Point(const Point& old) = default;
	Point& operator=(const Point& other) = default;

	// キャスト
	operator Point<ll>() const { return Point<ll>((ll)x, (ll)y); }
	operator Point<double>() const { return Point<double>((double)x, (double)y); }

	// 入出力
	friend istream& operator>>(istream& is, Point& p) { is >> p.x >> p.y; return is; }
	friend ostream& operator<<(ostream& os, const Point& p) { os << '(' << p.x << ',' << p.y << ')'; return os; }

	// 比較（x 座標優先）
	bool operator==(const Point& p) const { return x == p.x && y == p.y; }
	bool operator!=(const Point& p) const { return !(*this == p); }
	bool operator<(const Point& p) const { return x == p.x ? y < p.y : x < p.x; }
	bool operator>=(const Point& p) const { return !(*this < p); }
	bool operator>(const Point& p) const { return x == p.x ? y > p.y : x > p.x; }
	bool operator<=(const Point& p) const { return !(*this > p); }

	// 加算，減算，スカラー倍，スカラー除算
	Point& operator+=(const Point& p) { x += p.x; y += p.y;	return *this; }
	Point operator+(const Point& p) const { Point q(*this); return q += p; }
	Point& operator-=(const Point& p) { x -= p.x; y -= p.y;	return *this; }
	Point operator-(const Point& p) const { Point q(*this); return q -= p; }
	Point& operator*=(const T& c) { x *= c; y *= c;	return *this; }
	Point operator*(const T& c) const { Point q(*this); return q *= c; }
	Point& operator/=(const T& c) { x /= c; y /= c;	return *this; }
	Point operator/(const T& c) const { Point q(*this); return q /= c; }
	friend Point operator*(const T& sc, const Point& p) { return p * sc; }
	Point operator-() const { Point a = *this; return a *= -1; }

	// 二乗ノルム，ノルム，正規化
	T sqnorm() const { return x * x + y * y; }
	double norm() const { return sqrt((double)x * x + (double)y * y); }
	Point<double> normalize() const { return Point<double>(*this) / norm(); }

	// 内積，外積，成す角度
	T dot(const Point& other) const { return x * other.x + y * other.y; }
	T cross(const Point& other) const { return x * other.y - y * other.x; }
	double angle(const Point& other) const {
		return atan2(this->cross(other), this->dot(other));
	}
};


//【点の内外判定（円，直径指定）】O(1)
/*
* 2 点 a, b を直径の両端にもつ円 C と点 p の内外関係を判定する．
*
* 戻り値：
*	点 p が円 C の外部にあれば -1
*	点 p が円 C の境界にあれば 0
*	点 p が円 C の内部にあれば 1
*/
template <class T>
int inner_circle_by_diameter(const Point<T>& a, const Point<T>& b, const Point<T>& p) {
	// verify : https://atcoder.jp/contests/abc151/tasks/abc151_f

	//【方法】
	// タレスの定理の逆より，∠ a p b の大きさと 90°の大小を比較して判定できる．
	// 代わりに cos(∠ a p b) と cos(90°) = 0 の大小を比較して判定できる．
	// 代わりに内積 (p - a).(p - b) の符号を見て判定できる．

	T ip = (a - p).dot(b - p);

	if (ip > 0) return -1;
	if (ip < 0) return 1;
	return 0;
}


//【点の内外判定（円，3 点指定）】O(1)
/*
* 3 点 a, b, c を通る円 C と点 p の内外関係を判定する．
*
* 戻り値：
*	点 p が円 C の外部にあれば -1
*	点 p が円 C の境界にあれば 0
*	点 p が円 C の内部にあれば 1
*/
template <class T>
int inner_circle_by_3points(const Point<T>& a, const Point<T>& b, const Point<T>& c, const Point<T>& p) {
	// verify : https://atcoder.jp/contests/abc151/tasks/abc151_f

	//【方法】
	// a, b, c, p を複素平面上の点とみなせば，複比による共円判定条件より
	//		(b - c)(a - p) / (a - c)(b - p) ∈ R
	// なら 4 点 a, b, c, p は共円である．そうでないときは，p が無限遠点にあるときの
	//		(b - c) / (a - c)
	// と虚部の符号を比較して，等しいなら外部，異なるなら内部と判定できる．
	//
	// 複素数 num / dnm = (A + B i) / (C + D i) の虚部の符号の決定方法を考える．
	// 分母の実数化を行うと，
	//		(A + B i) / (C + D i)
	//		= (A + B i) (C - D i) / (C^2 + D^2)
	//		= ((A C + B D) + (- A D + B C) i) / (C^2 + D^2)
	// となる．分母は正の実数なので，- A D + B C の符号を見れば良い．

	T num_re = (b.x - c.x) * (a.x - p.x) - (b.y - c.y) * (a.y - p.y);
	T num_im = (b.x - c.x) * (a.y - p.y) + (b.y - c.y) * (a.x - p.x);
	T dnm_re = (a.x - c.x) * (b.x - p.x) - (a.y - c.y) * (b.y - p.y);
	T dnm_im = (a.x - c.x) * (b.y - p.y) + (a.y - c.y) * (b.x - p.x);
	T im = -num_re * dnm_im + num_im * dnm_re;

	if (im == 0) return 0;

	T num2_re = b.x - c.x;
	T num2_im = b.y - c.y;
	T dnm2_re = a.x - c.x;
	T dnm2_im = a.y - c.y;
	T im2 = -num2_re * dnm2_im + num2_im * dnm2_re;

	if ((im > 0) == (im2 > 0)) return -1;
	else return 1;
}


template <class T>
tuple<int, int, int> minimum_enclosing_circle(const vector<Point<T>>& p) {
	int n = sz(p);

	vi idx(n);
	iota(all(idx), 0);
	mt19937_64 mt((int)time(NULL));
	shuffle(all(idx), mt);

	int i1 = -1, i2 = -1, i3 = -1;

	rep(t, n) {
		int i = idx[t];

		if (i3 != -1 && inner_circle_by_3points(p[i1], p[i2], p[i3], p[i]) >= 0) continue;
		if (i3 == -1 && i2 != -1 && inner_circle_by_diameter(p[i1], p[i2], p[i]) >= 0) continue;
		i1 = i;
		i2 = -1;
		i3 = -1;

		rep(s, t) {
			int j = idx[s];

			if (i3 != -1 && inner_circle_by_3points(p[i1], p[i2], p[i3], p[j]) >= 0) continue;
			if (i3 == -1 && i2 != -1 && inner_circle_by_diameter(p[i1], p[i2], p[j]) >= 0) continue;
			i2 = j;
			i3 = -1;

			rep(u, s) {
				int k = idx[u];

				if (i3 != -1 && inner_circle_by_3points(p[i1], p[i2], p[i3], p[k]) >= 0) continue;
				if (i3 == -1 && i2 != -1 && inner_circle_by_diameter(p[i1], p[i2], p[k]) >= 0) continue;
				i3 = k;
			}
		}
	}

	return { i1, i2, i3 };
}


//【平面内の円】
/*
* {p, r} : 点 p を中心とする半径 r の円を表す．
*/
template <class T>
using Circle = pair<Point<T>, T>;


//【外接円】O(1)
/*
* 三角形 a b c の外接円を返す．
*/
template <class T>
Circle<double> circircle(const Point<T>& a, const Point<T>& b, const Point<T>& c) {
	// verify : https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/all/CGL_7_C

	//【方法】
	// Mathematica で
	//	Solve[(x1-x)^2 + (y1-y)^2 == (x2-x)^2 + (y2-y)^2 == (x3-x)^2 + (y3-y)^2, {x, y}] // FullSimplify
	// を実行し，結果を CForm[] して整形した．

	double x1 = a.x, y1 = a.y;
	double x2 = b.x, y2 = b.y;
	double x3 = c.x, y3 = c.y;

	double dnm = 2 * (x3 * (-y1 + y2) + x2 * (y1 - y3) + x1 * (-y2 + y3));

	Point<double> o;
	o.x = (x3 * x3 * (y2 - y1) + x2 * x2 * (y1 - y3)
		+ (x1 * x1 + (y1 - y2) * (y1 - y3)) * (y3 - y2)) / dnm;
	o.y = (y3 * y3 * (x1 - x2) + (y2 * y2) * (x3 - x1)
		+ ((y1 * y1) + (x1 - x2) * (x1 - x3)) * (x2 - x3)) / dnm;
	auto r = (Point<double>(a) - o).norm();
	return { o, r };
}


int main() {
//	input_from_file("input.txt");
//	output_to_file("output.txt");

	int n;
	cin >> n;

	vector<Point<__int128>> p(n);
	rep(i, n) {
		ll x, y;
		cin >> x >> y;

		p[i] = { x, y };
	}

	auto [i1, i2, i3] = minimum_enclosing_circle(p);
	dump(i1, i2, i3);

	if (i3 == -1) {
		double cx = (p[i1].x + p[i2].x) / 2.;
		double cy = (p[i1].y + p[i2].y) / 2.;
		double r = (p[i1] - p[i2]).norm() / 2.;

		cout << cx << " " << cy << " " << r << endl;
	}
	else {
		auto c = circircle(p[i1], p[i2], p[i3]);

		cout << c.first.x << " " << c.first.y << " " << c.second << endl;
	}
}
accuracy: 1
time_ms: 20
memory_kb: 6940
final_rank: 3

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

struct Point {
    double x, y;
};

double dist(const Point &a, const Point &b) {
    return hypot(a.x - b.x, a.y - b.y);
}

struct Circle {
    Point c;
    double r;
    Circle(Point _c = {0,0}, double _r = -1) : c(_c), r(_r) {}
};

bool is_in_circle(const Circle &C, const Point &p, double eps = 1e-9) {
    return dist(C.c, p) <= C.r + eps;
}

Circle circle2(const Point &a, const Point &b) {
    Point c{ (a.x + b.x) / 2.0, (a.y + b.y) / 2.0 };
    double r = dist(a, b) / 2.0;
    return Circle(c, r);
}

Circle circle3(const Point &a, const Point &b, const Point &c) {
    double d = 2 * (a.x*(b.y-c.y) + b.x*(c.y-a.y) + c.x*(a.y-b.y));
    if (fabs(d) < 1e-12) return Circle({0,0}, -1); // collinear

    double ux = ((a.x*a.x + a.y*a.y)*(b.y-c.y) + 
                 (b.x*b.x + b.y*b.y)*(c.y-a.y) + 
                 (c.x*c.x + c.y*c.y)*(a.y-b.y)) / d;
    double uy = ((a.x*a.x + a.y*a.y)*(c.x-b.x) + 
                 (b.x*b.x + b.y*b.y)*(a.x-c.x) + 
                 (c.x*c.x + c.y*c.y)*(b.x-a.x)) / d;
    Point o{ux, uy};
    double r = dist(o, a);
    return Circle(o, r);
}

Circle mec(vector<Point> &P) {
    random_shuffle(P.begin(), P.end());
    Circle C;
    for (int i = 0; i < (int)P.size(); i++) {
        if (C.r < 0 || !is_in_circle(C, P[i])) {
            C = Circle(P[i], 0);
            for (int j = 0; j < i; j++) {
                if (!is_in_circle(C, P[j])) {
                    C = circle2(P[i], P[j]);
                    for (int k = 0; k < j; k++) {
                        if (!is_in_circle(C, P[k])) {
                            Circle cc = circle3(P[i], P[j], P[k]);
                            if (cc.r >= 0) C = cc;
                        }
                    }
                }
            }
        }
    }
    return C;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

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

    Circle C = mec(P);
    const double eps = 1e-6;

    cout << fixed << setprecision(18);
    cout << C.c.x << " " << C.c.y << " " << C.r << "\n";
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 5376
final_rank: 6

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

using namespace std;

#define rep(i, l, r) for(int i = (l); i < (r); ++i)
#define FOR(i, l, r) for(int i = (l); i <= (r); ++i)
#define tcT template<class T
#define tcTU tcT, class U
#define mp make_pair
#define mt make_tuple
#define ff first
#define ss second
#define el "\n"
#define sz(v) (int)v.size()
#define all(v) begin(v), end(v)
#define rall(v) rbegin(v), rend(v)
#define pb push_back
#define eb emplace_back
#define compact(v) v.erase(unique(all(v)), end(v))

tcT> int lwb(const vector<T>& a, const T& b){ return int(lower_bound(all(a), b) - begin(a)); }
tcT> int upb(const vector<T>& a, const T& b){ return int(upper_bound(all(a), b) - begin(a)); }

using ll = long long;
using db = double;
using ld = long double;
using pi = pair<int, int>;
using pl = pair<ll, ll>;
using vi = vector<int>;
using vl = vector<ll>;
using vb = vector<bool>;
using vd = vector<db>;
using vc = vector<char>;
using vstr = vector<string>;
using vpi = vector<pi>;
using vpl = vector<pl>;

tcT> bool minimize(T& a, const T& b){ if(a > b) return a = b, true; return false; } 
tcT> bool maximize(T& a, const T& b){ if(a < b) return a = b, true; return false; } 
tcT> T ceil_div(T a, T b){ return (a / b) + ((a ^ b) > 0 && a % b); }
tcT> T floor_div(T a, T b){ return (a / b) - ((a ^ b) < 0 && a % b); }
tcT> void safe_erase(vector<T>& a, T x){
    auto it = find(all(a), x);
    if(it != a.end()) a.erase(it);
}

const auto start_time = std::chrono::high_resolution_clock::now();
db time_elapsed(){ return chrono::duration<db>(std::chrono::high_resolution_clock::now() - 
                                               start_time).count(); }

void setIO(){
    ios_base::sync_with_stdio(0); cin.tie(0);
#define task "task"
    if(fopen(task".inp", "r")){
        freopen(task".inp", "r", stdin);
        // freopen(task".out", "w", stdout);
    }
}

// Basic geometry objects: Point, Line, Segment
// Works with both integers and floating points
// Unless the problem has precision issue, can use Point, which uses double
// and has more functionalities.
// For integers, can use P<long long>
#ifndef EPS  // allow test files to overwrite EPS
#define EPS 1e-15
#endif
const double PI = acos(-1.0l);
double DEG_to_RAD(double d) { return d * PI / 180.0; }
double RAD_to_DEG(double r) { return r * 180.0 / PI; }
inline int cmp(double a, double b) { return (a < b - EPS) ? -1 : ((a > b + EPS) ? 1 : 0); }
// for int types
template<typename T, typename std::enable_if<!std::is_floating_point<T>::value>::type * = nullptr>
inline int cmp(T a, T b) { return (a == b) ? 0 : (a < b) ? -1 : 1; }
template<typename T>
struct P {
    T x, y;
    P() { x = y = T(0); }
    P(T _x, T _y) : x(_x), y(_y) {}

    P operator + (const P& a) const { return P(x+a.x, y+a.y); }
    P operator - (const P& a) const { return P(x-a.x, y-a.y); }
    P operator * (T k) const { return P(x*k, y*k); }
    P<double> operator / (double k) const { return P(x/k, y/k); }
    T operator * (const P& a) const { return x*a.x + y*a.y; } // dot product
    T operator % (const P& a) const { return x*a.y - y*a.x; } // cross product
    int cmp(const P<T>& q) const { if (int t = ::cmp(x,q.x)) return t; return ::cmp(y,q.y); }
    #define Comp(x) bool operator x (const P& q) const { return cmp(q) x 0; }
    Comp(>) Comp(<) Comp(==) Comp(>=) Comp(<=) Comp(!=)
    #undef Comp
    T norm() { return x*x + y*y; }
    double len() { return hypot(x, y); }
    P<double> rotate(double alpha) {
        double cosa = cos(alpha), sina = sin(alpha);
        return P(x * cosa - y * sina, x * sina + y * cosa);
    }
};
using Point = P<double>;

// Compare points by (y, x)
template<typename T = double>
bool cmpy(const P<T>& a, const P<T>& b) {
    if (cmp(a.y, b.y)) return a.y < b.y;
    return a.x < b.x;
};

template<typename T>
int ccw(P<T> a, P<T> b, P<T> c) {
    return cmp((b-a)%(c-a), T(0));
}

double angle(Point a, Point o, Point b) { // min of directed angle AOB & BOA
    a = a - o; b = b - o;
    return acos((a * b) / sqrt(a.norm()) / sqrt(b.norm()));
}

double directed_angle(Point a, Point o, Point b) { // angle AOB, in range [0, 2*PI)
    double t = -atan2(a.y - o.y, a.x - o.x)
            + atan2(b.y - o.y, b.x - o.x);
    while (t < 0) t += 2*PI;
    return t;
}

// Distance from p to Line ab (closest Point --> c)
// i.e. c is projection of p on AB
double distToLine(Point p, Point a, Point b, Point &c) {
    Point ap = p - a, ab = b - a;
    double u = (ap * ab) / ab.norm();
    c = a + (ab * u);
    return (p-c).len();
}

// Distance from p to segment ab (closest Point --> c)
double distToLineSegment(Point p, Point a, Point b, Point &c) {
    Point ap = p - a, ab = b - a;
    double u = (ap * ab) / ab.norm();
    if (u < 0.0) {
        c = Point(a.x, a.y);
        return (p - a).len();
    }
    if (u > 1.0) {
        c = Point(b.x, b.y);
        return (p - b).len();
    }
    return distToLine(p, a, b, c);
}

// NOTE: WILL NOT WORK WHEN a = b = 0.
struct Line {
    double a, b, c;  // ax + by + c = 0
    Point A, B;  // Added for polygon intersect line. Do not rely on assumption that these are valid

    Line(double _a, double _b, double _c) : a(_a), b(_b), c(_c) {} 

    Line(Point _A, Point _B) : A(_A), B(_B) {
        a = B.y - A.y;
        b = A.x - B.x;
        c = - (a * A.x + b * A.y);
    }
    Line(Point P, double m) {
        a = -m; b = 1;
        c = -((a * P.x) + (b * P.y));
    }
    double f(Point p) {
        return a*p.x + b*p.y + c;
    }
};
ostream& operator << (ostream& cout, const Line& l) {
    cout << l.a << "*x + " << l.b << "*y + " << l.c;
    return cout;
}

bool areParallel(Line l1, Line l2) {
    return cmp(l1.a*l2.b, l1.b*l2.a) == 0;
}

bool areSame(Line l1, Line l2) {
    return areParallel(l1 ,l2) && cmp(l1.c*l2.a, l2.c*l1.a) == 0
                && cmp(l1.c*l2.b, l1.b*l2.c) == 0;
}

bool areIntersect(Line l1, Line l2, Point &p) {
    if (areParallel(l1, l2)) return false;
    double dx = l1.b*l2.c - l2.b*l1.c;
    double dy = l1.c*l2.a - l2.c*l1.a;
    double d  = l1.a*l2.b - l2.a*l1.b;
    p = Point(dx/d, dy/d);
    return true;
}

// closest point from p in line l. (= projection of p onto line l)
void proj(Line l, Point p, Point &ans) {
    if (fabs(l.b) < EPS) {
        ans.x = -(l.c) / l.a; ans.y = p.y;
        return;
    }
    if (fabs(l.a) < EPS) {
        ans.x = p.x; ans.y = -(l.c) / l.b;
        return;
    }
    Line perp(l.b, -l.a, - (l.b*p.x - l.a*p.y));
    areIntersect(l, perp, ans);
}

// Tested:
// - https://cses.fi/problemset/task/2190/
template<typename T>
bool onSegment(const P<T>& a, const P<T>& b, const P<T>& p) { // returns true if p is on segment [a, b]
    return ccw(a, b, p) == 0  && min(a.x, b.x) <= p.x && p.x <= max(a.x, b.x) && min(a.y, b.y) <= p.y && p.y <= max(a.y, b.y);
}

// Returns true if segment [a, b] and [c, d] intersects
template<typename T>
bool segmentIntersect(const P<T>& a, const P<T>& b, const P<T>& c, const P<T>& d) {
    if (onSegment(a, b, c) || onSegment(a, b, d) || onSegment(c, d, a) || onSegment(c, d, b)) return true;
    return ccw(a, b, c) * ccw(a, b, d) < 0 && ccw(c, d, a) * ccw(c, d, b) < 0;
}

struct Circle : Point {
    double r;
    Circle(double _x = 0, double _y = 0, double _r = 0) : Point(_x, _y), r(_r) {}
    Circle(Point p, double _r) : Point(p), r(_r) {}
    
    bool contains(Point p) { return (*this - p).len() <= r + EPS; }
    double area() const { return r*r*M_PI; }
    // definitions in https://en.wikipedia.org/wiki/Circle
    // assumption: 0 <= theta <= 2*PI
    // theta: angle in radian
    double sector_area(double theta) const {
        return 0.5 * r * r * theta;
    }
    // assumption: 0 <= theta <= 2*PI
    // theta: angle in radian
    double segment_area(double theta) const {
        return 0.5 * r * r * (theta - sin(theta));
    }
};
istream& operator >> (istream& cin, Circle& c) {
    cin >> c.x >> c.y >> c.r;
    return cin;
}
ostream& operator << (ostream& cout, const Circle& c) {
    cout << '(' << c.x << ", " << c.y << ") " << c.r;
    return cout;
}
// Find common tangents to 2 circles
// Tested:
// - http://codeforces.com/gym/100803/ - H
// Helper method
void tangents(Point c, double r1, double r2, vector<Line> & ans) {
    double r = r2 - r1;
    #define sqr(x) (x)*(x)
    double z = sqr(c.x) + sqr(c.y);
    double d = z - sqr(r);
    if (d < -EPS)  return;
    d = sqrt(fabs(d));
    Line l((c.x * r + c.y * d) / z,
            (c.y * r - c.x * d) / z,
            r1);
    ans.push_back(l);
}
// Actual method: returns vector containing all common tangents
vector<Line> tangents(Circle a, Circle b) {
    vector<Line> ans; ans.clear();
    for (int i=-1; i<=1; i+=2)
        for (int j=-1; j<=1; j+=2)
            tangents(b-a, a.r*i, b.r*j, ans);
    for(int i = 0; i < (int) ans.size(); ++i)
        ans[i].c -= ans[i].a * a.x + ans[i].b * a.y;

    vector<Line> ret;
    for(int i = 0; i < (int) ans.size(); ++i) {
        if (std::none_of(ret.begin(), ret.end(), [&] (Line l) { return areSame(l, ans[i]); })) {
            ret.push_back(ans[i]);
        }
    }
    return ret;
}

// Circle & line intersection
// Tested:
// - http://codeforces.com/gym/100803/ - H
vector<Point> intersection(Line l, Circle cir) {
    double r = cir.r, a = l.a, b = l.b, c = l.c + l.a*cir.x + l.b*cir.y;
    vector<Point> res;

    double x0 = -a*c/(a*a+b*b),  y0 = -b*c/(a*a+b*b);
    if (c*c > r*r*(a*a+b*b)+EPS) return res;
    else if (fabs(c*c - r*r*(a*a+b*b)) < EPS) {
        res.push_back(Point(x0, y0) + Point(cir.x, cir.y));
        return res;
    } else {
        double d = r*r - c*c/(a*a+b*b);
        double mult = sqrt (d / (a*a+b*b));
        double ax,ay,bx,by;
        ax = x0 + b * mult;
        bx = x0 - b * mult;
        ay = y0 - a * mult;
        by = y0 + a * mult;

        res.push_back(Point(ax, ay) + Point(cir.x, cir.y));
        res.push_back(Point(bx, by) + Point(cir.x, cir.y));
        return res;
    }
}

// helper functions for commonCircleArea
double cir_area_solve(double a, double b, double c) {
    return acos((a*a + b*b - c*c) / 2 / a / b);
}
double cir_area_cut(double a, double r) {
    double s1 = a * r * r / 2;
    double s2 = sin(a) * r * r / 2;
    return s1 - s2;
}
// Tested: http://codeforces.com/contest/600/problem/D
double commonCircleArea(Circle c1, Circle c2) { //return the common area of two circle
    if (c1.r < c2.r) swap(c1, c2);
    double d = (c1 - c2).len();
    if (d + c2.r <= c1.r + EPS) return c2.r*c2.r*M_PI;
    if (d >= c1.r + c2.r - EPS) return 0.0;
    double a1 = cir_area_solve(d, c1.r, c2.r);
    double a2 = cir_area_solve(d, c2.r, c1.r);
    return cir_area_cut(a1*2, c1.r) + cir_area_cut(a2*2, c2.r);
}

// Check if 2 circle intersects. Return true if 2 circles touch
bool areIntersect(Circle u, Circle v) {
    if (cmp((u - v).len(), u.r + v.r) > 0) return false;
    if (cmp((u - v).len() + v.r, u.r) < 0) return false;
    if (cmp((u - v).len() + u.r, v.r) < 0) return false;
    return true;
}

// If 2 circle touches, will return 2 (same) points
// If 2 circle are same --> be careful
// Tested:
// - http://codeforces.com/gym/100803/ - H
// - http://codeforces.com/gym/100820/ - I
vector<Point> circleIntersect(Circle u, Circle v) {
    vector<Point> res;
    if (!areIntersect(u, v)) return res;
    double d = (u - v).len();
    double alpha = acos((u.r * u.r + d*d - v.r * v.r) / 2.0 / u.r / d);
    Point p1 = (v - u).rotate(alpha);
    Point p2 = (v - u).rotate(-alpha);
    res.push_back(p1 / p1.len() * u.r + u);
    res.push_back(p2 / p2.len() * u.r + u);
    return res;
}

// Smallest enclosing circle:
// Given N points. Find the smallest circle enclosing these points.
// Amortized complexity: O(N)
//
// Tested:
// - https://oj.vnoi.info/problem/icpc22_mt_l
struct SmallestEnclosingCircle {
    Circle getCircle(vector<Point> points) {
        assert(!points.empty());

        random_shuffle(points.begin(), points.end());
        Circle c(points[0], 0);
        int n = points.size();

        for (int i = 1; i < n; i++)
            if ((points[i] - c).len() > c.r + EPS){
                c = Circle(points[i], 0);
                for (int j = 0; j < i; j++)
                    if ((points[j] - c).len() > c.r + EPS){
                        c = Circle((points[i] + points[j]) / 2, (points[i] - points[j]).len() / 2);
                        for (int k = 0; k < j; k++)
                            if ((points[k] - c).len() > c.r + EPS)
                                c = getCircumcircle(points[i], points[j], points[k]);
                    }
            }

        return c;
    }
    // NOTE: This code work only when a, b, c are not collinear and no 2 points are same --> DO NOT
    // copy and use in other cases.
    Circle getCircumcircle(Point a, Point b, Point c) {
        assert(ccw(a, b, c));
        double d = 2.0 * (a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y));
        assert(fabs(d) > EPS);
        double x = (a.norm() * (b.y - c.y) + b.norm() * (c.y - a.y) + c.norm() * (a.y - b.y)) / d;
        double y = (a.norm() * (c.x - b.x) + b.norm() * (a.x - c.x) + c.norm() * (b.x - a.x)) / d;
        Point p(x, y);
        return Circle(p, (p - a).len());
    }
};

int n;
vector<Point>points;

void testcase(int n_case){
    cin >> n;
    points.resize(n);
    rep(i, 0, n) {
        cin >> points[i].x >> points[i].y;
    }

    SmallestEnclosingCircle c;
    Circle ans = c.getCircle(points);
    cout << fixed << setprecision(8) << ans.x << " " << ans.y << " " << ans.r << el;
}

int main(){
    setIO();
    int T = 1; 
    // cin >> T;
    rep(i, 0, T) testcase(i);
    // cerr << '\n' << "Execution time : " << (time_elapsed() * 1000.0) << " ms";
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 6308
final_rank: 12

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

using namespace std;

#define tcT template<class T
#define tcTU tcT, class U

#define all(v) begin(v), end(v)
#define rall(v) rbegin(v), rend(v)
#define sz(v) (int)v.size()
#define compact(v) v.erase(unique(all(v)), end(v))
#define pb push_back
#define eb emplace_back

#define FOR(i, l, r) for(int i = (l); i <= (r); ++i)
#define rep(i, l, r) for(int i = (l); i < (r); ++i)

#define mp make_pair
#define mt make_tuple
#define ff first
#define ss second

using ll = long long;
using db = double;
using ull = unsigned long long;
using ld = long double;
using str = string;

using pi = pair<int, int>;
using pl = pair<ll, ll>;

using vi = vector<int>;
using vl = vector<ll>;
using vd = vector<db>;
using vc = vector<char>;
using vb = vector<bool>;
using vstr = vector<str>;

using vpi = vector<pi>;
using vpl = vector<pl>;

tcT> using min_heap = priority_queue<T, vector<T>, greater<T>>;
tcT> using max_heap = priority_queue<T>;

tcT> bool minimize(T& a, const T& b){
    if(a > b) return a = b, true;
    return false;
}

tcT> bool maximize(T& a, const T& b){
    if(a < b) return a = b, true;
    return false;
}

#ifdef LOCAL
    #define dbg(...) (cerr << "#" << __LINE__ << " | " << "[" << #__VA_ARGS__ << "] = ", print(__VA_ARGS__))

    template<class A, class B> ostream& operator << (ostream& stream, const pair<A, B>& p){ return stream << '(' << p.ff << ',' << p.ss << ')'; }
    template<class T> void print_one(const T& x){ cerr << x; }
    template<class It> void print_range(It a, It b){
        cerr << '{';
        bool first = true;
        for(It it = a; it != b; ++it){
            if(!first) cerr << ",";
            print_one(*it);
            first = false;
        }
        cerr << '}';
    }

    template<class T> void print_one(const vector<T>& v){ print_range(v.begin(), v.end()); }
    template<class T> void print_one(const set<T>& v){ print_range(v.begin(), v.end()); }
    template<class T> void print_one(const multiset<T>& v){ print_range(v.begin(), v.end()); }
    template<class T, class U> void print_one(const map<T, U>& m){
        cerr << '{';
        bool first = true;
        for(auto& kv : m){
            if(!first) cerr << ',';
            cerr << '('; print_one(kv.ff); cerr << ": "; print_one(kv.ss); cerr << ')';
        }
        cerr << '}';
    }

    inline void print(){ cerr << '\n'; }
    template<class T> void print(const T& v){ print_one(v); cerr << '\n'; }
    template<class T, class...U> void print(const T& a, const U&...b){
        print_one(a); cerr << ", ";
        print(b...);
    }
#else
    #define dbg(...) ((void)0)
#endif // LOCAL

void setIO(){
    ios_base::sync_with_stdio(0); cin.tie(0);
#define task "task"
    if(fopen(task".inp", "r")){
        freopen(task".inp", "r", stdin);
        freopen(task".out", "w", stdout);
    }
}

#define sqr(x) ((x) * (x))
#define FORD(i,a,b) for(int i=(a),_b=(b); i>=_b; i--)
#define REP(i,a) for(int i=0,_a=(a); i<_a; i++)
#define EACH(it,a) for(__typeof(a.begin()) it = a.begin(); it != a.end(); ++it)

// Basic geometry objects: Point, Line, Segment
// Works with both integers and floating points
// Unless the problem has precision issue, can use Point, which uses double
// and has more functionalities.
// For integers, can use P<long long>
#ifndef EPS  // allow test files to overwrite EPS
#define EPS 1e-15
#endif
const double PI = acos(-1.0l);
double DEG_to_RAD(double d) { return d * PI / 180.0; }
double RAD_to_DEG(double r) { return r * 180.0 / PI; }
inline int cmp(double a, double b) { return (a < b - EPS) ? -1 : ((a > b + EPS) ? 1 : 0); }
// for int types
template<typename T, typename std::enable_if<!std::is_floating_point<T>::value>::type * = nullptr>
inline int cmp(T a, T b) { return (a == b) ? 0 : (a < b) ? -1 : 1; }
template<typename T>
struct P {
    T x, y;
    P() { x = y = T(0); }
    P(T _x, T _y) : x(_x), y(_y) {}

    P operator + (const P& a) const { return P(x+a.x, y+a.y); }
    P operator - (const P& a) const { return P(x-a.x, y-a.y); }
    P operator * (T k) const { return P(x*k, y*k); }
    P<double> operator / (double k) const { return P(x/k, y/k); }
    T operator * (const P& a) const { return x*a.x + y*a.y; } // dot product
    T operator % (const P& a) const { return x*a.y - y*a.x; } // cross product
    int cmp(const P<T>& q) const { if (int t = ::cmp(x,q.x)) return t; return ::cmp(y,q.y); }
    #define Comp(x) bool operator x (const P& q) const { return cmp(q) x 0; }
    Comp(>) Comp(<) Comp(==) Comp(>=) Comp(<=) Comp(!=)
    #undef Comp
    T norm() { return x*x + y*y; }
    double len() { return hypot(x, y); }
    P<double> rotate(double alpha) {
        double cosa = cos(alpha), sina = sin(alpha);
        return P(x * cosa - y * sina, x * sina + y * cosa);
    }
};
using Point = P<double>;

// Compare points by (y, x)
template<typename T = double>
bool cmpy(const P<T>& a, const P<T>& b) {
    if (cmp(a.y, b.y)) return a.y < b.y;
    return a.x < b.x;
};

template<typename T>
int ccw(P<T> a, P<T> b, P<T> c) {
    return cmp((b-a)%(c-a), T(0));
}

double angle(Point a, Point o, Point b) { // min of directed angle AOB & BOA
    a = a - o; b = b - o;
    return acos((a * b) / sqrt(a.norm()) / sqrt(b.norm()));
}

double directed_angle(Point a, Point o, Point b) { // angle AOB, in range [0, 2*PI)
    double t = -atan2(a.y - o.y, a.x - o.x)
            + atan2(b.y - o.y, b.x - o.x);
    while (t < 0) t += 2*PI;
    return t;
}

// Distance from p to Line ab (closest Point --> c)
// i.e. c is projection of p on AB
double distToLine(Point p, Point a, Point b, Point &c) {
    Point ap = p - a, ab = b - a;
    double u = (ap * ab) / ab.norm();
    c = a + (ab * u);
    return (p-c).len();
}

// Distance from p to segment ab (closest Point --> c)
double distToLineSegment(Point p, Point a, Point b, Point &c) {
    Point ap = p - a, ab = b - a;
    double u = (ap * ab) / ab.norm();
    if (u < 0.0) {
        c = Point(a.x, a.y);
        return (p - a).len();
    }
    if (u > 1.0) {
        c = Point(b.x, b.y);
        return (p - b).len();
    }
    return distToLine(p, a, b, c);
}

// NOTE: WILL NOT WORK WHEN a = b = 0.
struct Line {
    double a, b, c;  // ax + by + c = 0
    Point A, B;  // Added for polygon intersect line. Do not rely on assumption that these are valid

    Line(double _a, double _b, double _c) : a(_a), b(_b), c(_c) {} 

    Line(Point _A, Point _B) : A(_A), B(_B) {
        a = B.y - A.y;
        b = A.x - B.x;
        c = - (a * A.x + b * A.y);
    }
    Line(Point P, double m) {
        a = -m; b = 1;
        c = -((a * P.x) + (b * P.y));
    }
    double f(Point p) {
        return a*p.x + b*p.y + c;
    }
};
ostream& operator << (ostream& cout, const Line& l) {
    cout << l.a << "*x + " << l.b << "*y + " << l.c;
    return cout;
}

bool areParallel(Line l1, Line l2) {
    return cmp(l1.a*l2.b, l1.b*l2.a) == 0;
}

bool areSame(Line l1, Line l2) {
    return areParallel(l1 ,l2) && cmp(l1.c*l2.a, l2.c*l1.a) == 0
                && cmp(l1.c*l2.b, l1.b*l2.c) == 0;
}

bool areIntersect(Line l1, Line l2, Point &p) {
    if (areParallel(l1, l2)) return false;
    double dx = l1.b*l2.c - l2.b*l1.c;
    double dy = l1.c*l2.a - l2.c*l1.a;
    double d  = l1.a*l2.b - l2.a*l1.b;
    p = Point(dx/d, dy/d);
    return true;
}

// closest point from p in line l. (= projection of p onto line l)
void proj(Line l, Point p, Point &ans) {
    if (fabs(l.b) < EPS) {
        ans.x = -(l.c) / l.a; ans.y = p.y;
        return;
    }
    if (fabs(l.a) < EPS) {
        ans.x = p.x; ans.y = -(l.c) / l.b;
        return;
    }
    Line perp(l.b, -l.a, - (l.b*p.x - l.a*p.y));
    areIntersect(l, perp, ans);
}

// Tested:
// - https://cses.fi/problemset/task/2190/
template<typename T>
bool onSegment(const P<T>& a, const P<T>& b, const P<T>& p) { // returns true if p is on segment [a, b]
    return ccw(a, b, p) == 0  && min(a.x, b.x) <= p.x && p.x <= max(a.x, b.x) && min(a.y, b.y) <= p.y && p.y <= max(a.y, b.y);
}

// Returns true if segment [a, b] and [c, d] intersects
template<typename T>
bool segmentIntersect(const P<T>& a, const P<T>& b, const P<T>& c, const P<T>& d) {
    if (onSegment(a, b, c) || onSegment(a, b, d) || onSegment(c, d, a) || onSegment(c, d, b)) return true;
    return ccw(a, b, c) * ccw(a, b, d) < 0 && ccw(c, d, a) * ccw(c, d, b) < 0;
}

struct Circle : Point {
    double r;
    Circle(double _x = 0, double _y = 0, double _r = 0) : Point(_x, _y), r(_r) {}
    Circle(Point p, double _r) : Point(p), r(_r) {}
    
    bool contains(Point p) { return (*this - p).len() <= r + EPS; }
    double area() const { return r*r*M_PI; }
    // definitions in https://en.wikipedia.org/wiki/Circle
    // assumption: 0 <= theta <= 2*PI
    // theta: angle in radian
    double sector_area(double theta) const {
        return 0.5 * r * r * theta;
    }
    // assumption: 0 <= theta <= 2*PI
    // theta: angle in radian
    double segment_area(double theta) const {
        return 0.5 * r * r * (theta - sin(theta));
    }
};
istream& operator >> (istream& cin, Circle& c) {
    cin >> c.x >> c.y >> c.r;
    return cin;
}
ostream& operator << (ostream& cout, const Circle& c) {
    cout << '(' << c.x << ", " << c.y << ") " << c.r;
    return cout;
}
// Find common tangents to 2 circles
// Tested:
// - http://codeforces.com/gym/100803/ - H
// Helper method
void tangents(Point c, double r1, double r2, vector<Line> & ans) {
    double r = r2 - r1;
    double z = sqr(c.x) + sqr(c.y);
    double d = z - sqr(r);
    if (d < -EPS)  return;
    d = sqrt(fabs(d));
    Line l((c.x * r + c.y * d) / z,
            (c.y * r - c.x * d) / z,
            r1);
    ans.push_back(l);
}
// Actual method: returns vector containing all common tangents
vector<Line> tangents(Circle a, Circle b) {
    vector<Line> ans; ans.clear();
    for (int i=-1; i<=1; i+=2)
        for (int j=-1; j<=1; j+=2)
            tangents(b-a, a.r*i, b.r*j, ans);
    for(int i = 0; i < (int) ans.size(); ++i)
        ans[i].c -= ans[i].a * a.x + ans[i].b * a.y;

    vector<Line> ret;
    for(int i = 0; i < (int) ans.size(); ++i) {
        if (std::none_of(ret.begin(), ret.end(), [&] (Line l) { return areSame(l, ans[i]); })) {
            ret.push_back(ans[i]);
        }
    }
    return ret;
}

// Circle & line intersection
// Tested:
// - http://codeforces.com/gym/100803/ - H
vector<Point> intersection(Line l, Circle cir) {
    double r = cir.r, a = l.a, b = l.b, c = l.c + l.a*cir.x + l.b*cir.y;
    vector<Point> res;

    double x0 = -a*c/(a*a+b*b),  y0 = -b*c/(a*a+b*b);
    if (c*c > r*r*(a*a+b*b)+EPS) return res;
    else if (fabs(c*c - r*r*(a*a+b*b)) < EPS) {
        res.push_back(Point(x0, y0) + Point(cir.x, cir.y));
        return res;
    } else {
        double d = r*r - c*c/(a*a+b*b);
        double mult = sqrt (d / (a*a+b*b));
        double ax,ay,bx,by;
        ax = x0 + b * mult;
        bx = x0 - b * mult;
        ay = y0 - a * mult;
        by = y0 + a * mult;

        res.push_back(Point(ax, ay) + Point(cir.x, cir.y));
        res.push_back(Point(bx, by) + Point(cir.x, cir.y));
        return res;
    }
}

// helper functions for commonCircleArea
double cir_area_solve(double a, double b, double c) {
    return acos((a*a + b*b - c*c) / 2 / a / b);
}
double cir_area_cut(double a, double r) {
    double s1 = a * r * r / 2;
    double s2 = sin(a) * r * r / 2;
    return s1 - s2;
}
// Tested: http://codeforces.com/contest/600/problem/D
double commonCircleArea(Circle c1, Circle c2) { //return the common area of two circle
    if (c1.r < c2.r) swap(c1, c2);
    double d = (c1 - c2).len();
    if (d + c2.r <= c1.r + EPS) return c2.r*c2.r*M_PI;
    if (d >= c1.r + c2.r - EPS) return 0.0;
    double a1 = cir_area_solve(d, c1.r, c2.r);
    double a2 = cir_area_solve(d, c2.r, c1.r);
    return cir_area_cut(a1*2, c1.r) + cir_area_cut(a2*2, c2.r);
}

// Check if 2 circle intersects. Return true if 2 circles touch
bool areIntersect(Circle u, Circle v) {
    if (cmp((u - v).len(), u.r + v.r) > 0) return false;
    if (cmp((u - v).len() + v.r, u.r) < 0) return false;
    if (cmp((u - v).len() + u.r, v.r) < 0) return false;
    return true;
}

// If 2 circle touches, will return 2 (same) points
// If 2 circle are same --> be careful
// Tested:
// - http://codeforces.com/gym/100803/ - H
// - http://codeforces.com/gym/100820/ - I
vector<Point> circleIntersect(Circle u, Circle v) {
    vector<Point> res;
    if (!areIntersect(u, v)) return res;
    double d = (u - v).len();
    double alpha = acos((u.r * u.r + d*d - v.r * v.r) / 2.0 / u.r / d);
    Point p1 = (v - u).rotate(alpha);
    Point p2 = (v - u).rotate(-alpha);
    res.push_back(p1 / p1.len() * u.r + u);
    res.push_back(p2 / p2.len() * u.r + u);
    return res;
}

// Smallest enclosing circle:
// Given N points. Find the smallest circle enclosing these points.
// Amortized complexity: O(N)
//
// Tested:
// - https://oj.vnoi.info/problem/icpc22_mt_l
struct SmallestEnclosingCircle {
    Circle getCircle(vector<Point> points) {
        assert(!points.empty());

        random_shuffle(points.begin(), points.end());
        Circle c(points[0], 0);
        int n = points.size();

        for (int i = 1; i < n; i++)
            if ((points[i] - c).len() > c.r + EPS){
                c = Circle(points[i], 0);
                for (int j = 0; j < i; j++)
                    if ((points[j] - c).len() > c.r + EPS){
                        c = Circle((points[i] + points[j]) / 2, (points[i] - points[j]).len() / 2);
                        for (int k = 0; k < j; k++)
                            if ((points[k] - c).len() > c.r + EPS)
                                c = getCircumcircle(points[i], points[j], points[k]);
                    }
            }

        return c;
    }
    // NOTE: This code work only when a, b, c are not collinear and no 2 points are same --> DO NOT
    // copy and use in other cases.
    Circle getCircumcircle(Point a, Point b, Point c) {
        assert(ccw(a, b, c));
        double d = 2.0 * (a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y));
        assert(fabs(d) > EPS);
        double x = (a.norm() * (b.y - c.y) + b.norm() * (c.y - a.y) + c.norm() * (a.y - b.y)) / d;
        double y = (a.norm() * (c.x - b.x) + b.norm() * (a.x - c.x) + c.norm() * (b.x - a.x)) / d;
        Point p(x, y);
        return Circle(p, (p - a).len());
    }
};

void testcase(){
    int N;
    cin >> N;
    vector<Point> pts(N);

    rep(i, 0, N){
        int x, y;
        cin >> x >> y;
        pts[i] = Point(x, y);
    }

    SmallestEnclosingCircle C;
    Circle result = C.getCircle(pts);

    cout << fixed << setprecision(12) << result.x << ' ' << result.y << ' ' << result.r << '\n';
}

int main(){
    setIO();
    int T = 1;
    // cin >> T;
    while(T--){
        testcase();
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 6252
final_rank: 2