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: Wrong Answer)

#include <iostream>
#include <string>
#include <utility>
#include <queue>
#include <cstdio>
#include <cmath>
#include <algorithm>
#define llint long long
#define inf 1e18
#define eps 1e-9
#define mod 1000000007

using namespace std;
typedef pair<llint, llint> P;

struct vec2d{
	double x, y;
	vec2d(){}
	vec2d(double x, double y){
		this->x = x, this->y = y;
	}
	double add(double a, double b){
		if(fabs(a+b) < eps * (fabs(a) + fabs(b))) return 0.0;
		return a+b;
	}
	vec2d operator+(vec2d ope){
		return vec2d(add(x, ope.x), add(y, ope.y));
	}
	vec2d operator-(vec2d ope){
		return vec2d(add(x, -ope.x), add(y, -ope.y));
	}
	vec2d operator*(double t){
		return vec2d(x*t, y*t);
	}
	vec2d operator/(double t){
		return vec2d(x/t, y/t);
	}
	double dot(vec2d ope){
		return add(x*ope.x, y*ope.y);
	}
	double cross(vec2d ope){
		return add(x*ope.y, -y*ope.x);
	}
	double norm(){
		double d2 = dot(*this);
		if(d2 > 0) return sqrt(d2);
		return 0.0;
	}
};

double distPP(vec2d p, vec2d q){
	return (p-q).norm();
}

double distSP(vec2d p, vec2d q, vec2d x)
{
	if((x-p).dot(q-p) <= 0) return distPP(p, x);
	if((x-q).dot(p-q) <= 0) return distPP(q, x);
	return fabs( (x-p).cross(q-p) / distPP(p, q) );
}

bool isOnS(vec2d p, vec2d q, vec2d x)
{
	return (p-x).cross(q-x) == 0 && (p-x).dot(q-x) <= 0;
}

bool isCross(vec2d p, vec2d q, vec2d r, vec2d s)
{
	if((q-p).cross(s-r) == 0){
		return isOnS(p, q, r) || isOnS(p, q, s) || isOnS(r, s, p) || isOnS(r, s, q);	
	}
	double t = (r-p).cross(s-r) / (q-p).cross(s-r);
	vec2d x = p + (q-p)*t;
	return isOnS(p, q, x) && isOnS(r, s, x);
}

bool getCross(vec2d p, vec2d q, vec2d r, vec2d s, vec2d &ret)
{
	if((q-p).cross(s-r) == 0){
		return false;
	}
	double t = (r-p).cross(s-r) / (q-p).cross(s-r);
	ret = p + (q-p)*t;
	return true;
}

llint n;
vec2d p[55];

bool get(vec2d o, vec2d a, vec2d b, vec2d &ret)
{
	vec2d A = (o + a) * 0.5, B = (o + b) * 0.5;
	vec2d nA = vec2d(A.y, -A.x), nB = vec2d(B.y, -B.x);
	nA = nA / nA.norm(), nB = nB / nB.norm();
	//cout << o.x << " " << o.y << " " << a.x << " "  << a.y << " " << b.x << " " << b.y << endl;
	return getCross(A, A+nA, B, B+nB, ret);
}

bool check(double r)
{
	for(int i = 1; i <= n; i++){
		for(int j = i+1; j <= n; j++){
			vec2d c = (p[i] + p[j]) * 0.5;
			bool flag = true;
			for(int l = 1; l <= n; l++){
				if(distPP(c, p[l]) > r + eps){
					flag = false;
					break;
				}
			}
			if(flag) return true;
		}
	}
	for(int i = 1; i <= n; i++){
		for(int j = i+1; j <= n; j++){
			for(int k = j+1; k <= n; k++){
				vec2d c;
				if(!get(p[i], p[j], p[k], c)) continue;
				//cout << c.x << " " << c.y << endl;
				bool flag = true;
				for(int l = 1; l <= n; l++){
					if(distPP(c, p[l]) > r + eps){
						flag = false;
						break;
					}
				}
				if(flag) return true;
			}
		}
	}
	return false;
}

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> n;
	for(int i = 1; i <= n; i++) cin >> p[i].x >> p[i].y;
	
	if(n == 2){
		printf("%.11f\n", distPP(p[1], p[2])*0.5);
		return 0;
	}
	
	double ans = inf;
	
	for(int i = 1; i <= n; i++){
		for(int j = i+1; j <= n; j++){
			vec2d c = (p[i] + p[j]) * 0.5;
			double r = distPP(c, p[i]);
			bool flag = true;
			for(int l = 1; l <= n; l++){
				if(distPP(c, p[l]) > r + eps){
					flag = false;
					break;
				}
			}
			if(flag) ans = min(ans, r);
		}
	}
	for(int i = 1; i <= n; i++){
		for(int j = i+1; j <= n; j++){
			for(int k = j+1; k <= n; k++){
				vec2d c;
				double r = distPP(c, p[i]);
				if(!get(p[i], p[j], p[k], c)) continue;
				//cout << c.x << " " << c.y << endl;
				bool flag = true;
				for(int l = 1; l <= n; l++){
					if(distPP(c, p[l]) > r + eps){
						flag = false;
						break;
					}
				}
				if(flag) ans = min(ans, r);
			}
		}
	}
	printf("%.11f\n", ans);
	
	return 0;
}