Problem:
Score : 600 points

Problem Statement

Given are N points (x_i, y_i) in a two-dimensional plane.

Find the minimum radius of a circle such that all the points are inside or on it.

Constraints

2 \leq N \leq 50

0 \leq x_i \leq 1000

0 \leq y_i \leq 1000

The given N points are all different.

The values in input are all integers.

Input

Input is given from Standard Input in the following format:

N
x_1 y_1
:
x_N y_N

Output

Print the minimum radius of a circle such that all the N points are inside or on it.

Your output will be considered correct if the absolute or relative error from our answer is at most 10^{-6}.

Sample Input 1

2
0 0
1 0

Sample Output 1

0.500000000000000000

Both points are contained in the circle centered at (0.5,0) with a radius of 0.5.

Sample Input 2

3
0 0
0 1
1 0

Sample Output 2

0.707106781186497524

Sample Input 3

10
10 9
5 9
2 0
0 0
2 7
3 3
2 5
10 0
3 7
1 9

Sample Output 3

6.726812023536805158

If the absolute or relative error from our answer is at most 10^{-6}, the output will be considered correct.

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;
using LL = long long int;
#define incID(i, l, r) for(int i = (l)    ; i <  (r); ++i)
#define decID(i, l, r) for(int i = (r) - 1; i >= (l); --i)
#define incII(i, l, r) for(int i = (l)    ; i <= (r); ++i)
#define decII(i, l, r) for(int i = (r)    ; i >= (l); --i)
#define inc(i, n)  incID(i, 0, n)
#define dec(i, n)  decID(i, 0, n)
#define inc1(i, n) incII(i, 1, n)
#define dec1(i, n) decII(i, 1, n)
#define inID(v, l, r) ((l) <= (v) && (v) <  (r))
#define inII(v, l, r) ((l) <= (v) && (v) <= (r))
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define FI first
#define SE second
#define FR front()
#define BA back()
#define ALL(v) v.begin(), v.end()
#define RALL(v) v.rbegin(), v.rend()
auto setmin   = [](auto & a, auto b) { return (b <  a ? a = b, true : false); };
auto setmax   = [](auto & a, auto b) { return (b >  a ? a = b, true : false); };
auto setmineq = [](auto & a, auto b) { return (b <= a ? a = b, true : false); };
auto setmaxeq = [](auto & a, auto b) { return (b >= a ? a = b, true : false); };
#define SI(v) static_cast<int>(v.size())
#define RF(e, v) for(auto & e: v)
#define until(e) while(! (e))
#define if_not(e) if(! (e))
#define ef else if
#define UR assert(false)
#define IN(T, ...) T __VA_ARGS__; IN_(__VA_ARGS__);
void IN_() { };
template<typename T, typename ... U> void IN_(T & a, U & ... b) { cin >> a; IN_(b ...); };
template<typename T> void OUT(T && a) { cout << a << endl; }
template<typename T, typename ... U> void OUT(T && a, U && ... b) { cout << a << " "; OUT(b ...); }

// ---- ----

#include <boost/multiprecision/cpp_int.hpp>
using Z = boost::multiprecision::cpp_int;
#include <boost/rational.hpp>
using Q = boost::rational<Z>;
#include <boost/multiprecision/cpp_dec_float.hpp>
template<int N> using R = boost::multiprecision::number<boost::multiprecision::cpp_dec_float<N>>;

template<typename T> struct Point {
	T x, y;
	Point(T x, T y) : x(x), y(y) { };
	friend Point operator+(Point a, Point b) { return { a.x + b.x, a.y + b.y }; }
	friend Point operator-(Point a, Point b) { return { a.x - b.x, a.y - b.y }; }
	friend Point operator*(Point a, T     b) { return { a.x * b, a.y * b }; }
	friend Point operator*(T     a, Point b) { return b * a; }
	friend Point operator/(Point a, T     b) { return { a.x / b, a.y / b }; } // -Wno-maybe-uninitialized
};
auto sq = [](auto x) { return x * x; };
auto dist2 = [](auto a, auto b) { return sq(a.x - b.x) + sq(a.y - b.y); };
auto dot   = [](auto a, auto b) { return a.x * b.x + a.y * b.y; };
auto cross = [](auto a, auto b) { return a.x * b.y - a.y * b.x; };
auto triangle_circumcenter = [](auto a, auto b, auto c) {
	if(cross(b - a, c - a) == 0) {
		if(dot(b - a, c - a) < 0) { return (b + c) / Q(2); }
		if(dot(c - b, a - b) < 0) { return (c + a) / Q(2); }
		if(dot(a - c, b - c) < 0) { return (a + b) / Q(2); }
		UR;
	}
	auto a2 = dist2(b, c);
	auto b2 = dist2(c, a);
	auto c2 = dist2(a, b);
	auto p = a2 * (- a2 + b2 + c2);
	auto q = b2 * (+ a2 - b2 + c2);
	auto r = c2 * (+ a2 + b2 - c2);
	assert(p + q + r != 0);
	return (p * a + q * b + r * c) / (p + q + r);
};

int main() {
	IN(int, n);
	vector<Point<Q>> v;
	inc(i, n) { IN(int, x, y); v.EB(Q(x), Q(y)); }
	
	auto ok = [&](Point<Q> p, Q d2) {
		inc(i, n) {
			if(d2 < dist2(p, v[i])) { return false; }
		}
		return true;
	};
	
	Q ans2(4'000'000);
	inc(i, n) {
	inc(j, i) {
		Point<Q> m = (v[i] + v[j]) / Q(2);
		Q r2 = dist2(m, v[i]);
		if(ok(m, r2)) { setmin(ans2, r2); }
	}
	}
	inc(i, n) {
	inc(j, i) {
	inc(k, j) {
		Point<Q> m = triangle_circumcenter(v[i], v[j], v[k]);
		Q r2 = dist2(m, v[i]);
		if(ok(m, r2)) { setmin(ans2, r2); }
	}
	}
	}
	R<40> ans = sqrt(boost::rational_cast<R<40>>(ans2));
	OUT(ans.str());
}