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# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using Vector = Point;

public struct Point
{
    public double X;
    public double Y;

    public Point(Point p)
    {
        X = p.X;
        Y = p.Y;
    }

    public Point(double x, double y)
    {
        X = x;
        Y = y;
    }


    public static Point operator +(Point a, Point b)
    {
        return new Point(a.X + b.X, a.Y + b.Y);
    }

    public static Point operator -(Point a, Point b)
    {
        return new Point(a.X - b.X, a.Y - b.Y);
    }

    public static Point operator *(Point a, int i)
    {
        return new Point(a.X * i, a.Y * i);
    }

    public static Point operator /(Point a, int i)
    {
        return new Point(a.X / i, a.Y / i);
    }
    public static Point operator +(Point a)
    {
        return new Point(+a.X, +a.Y);
    }

    public static Point operator -(Point a)
    {
        return new Point(-a.X, -a.Y);
    }

    public override string ToString()
    {
        return string.Format("({0},{1})", X, Y);
    }

    public double Norm()
    {
        return Math.Sqrt(X * X + Y * Y);
    }

    public double Norm2()
    {
        return X * X + Y * Y;
    }

    public double Distance(Point that)
    {
        return (that - this).Norm();
    }

    public double Distance2(Point that)
    {
        return (that - this).Norm2();
    }
}

public struct Circle
{
    public readonly Point P;
    public readonly double R;

    public Circle(Point p, double r)
    {
        P = p;
        R = r;
    }

    // 交点を取得
    public List<Point> GetCrossPoint(Circle that)
    {
        List<Point> cross = new List<Point>();

        // 円の中心間のベクトル:
        Vector v = new Vector(that.P.X - P.X, that.P.Y - P.Y);
        // vの長さ
        double d = v.Norm();
        // X軸に対するvの角度:
        double a = Math.Atan2(that.P.Y - P.Y, that.P.X - P.X);
        // 偏角s
        double s = Math.Acos((d * d + R * R - that.R * that.R) / (2 * d * R));

        if (Math.Abs(R - that.R) < d && d < R + that.R)
        {
            //円は交わっている
            //交点は2つ
            Point p1 = new Point(P.X + R * Math.Cos(a + s), P.Y + R * Math.Sin(a + s));
            Point p2 = new Point(P.X + R * Math.Cos(a - s), P.Y + R * Math.Sin(a - s));
            cross.Add(p1);
            cross.Add(p2);
        }
        else if ((Math.Abs(R - that.R) == d || R + that.R == d) && d != 0)
        {
            //円は外接か内接し一致せず
            //交点は1つ
            Point p1 = new Point(P.X + R * Math.Cos(a + s), P.Y + R * Math.Sin(a + s));
            cross.Add(p1);
        }

        return cross;
    }
}

public class Solution
{
    const double e = 1e-9;

    // [ok,ng) or (ng,ok]
    static double Search(double ok, double ng, Point[] points)
    {
        while (Math.Abs(ok - ng) > e)
        {
            var mid = (ok + ng) / 2;
            if (Solve(points, mid))
            {
                ok = mid;
            }
            else
            {
                ng = mid;
            }
            Console.Error.WriteLine($"ok:{ok} ng:{ng}");
        }
        return ok;
    }

    static bool Solve(Point[] points, double r)
    {
        var circles = points.Select(p => new Circle(p, r)).ToArray();
        var n = circles.Length;
        var r2 = r * r;
        for (int i = 0; i < n; i++)
        {
            for (int j = i + 1; j < n; j++)
            {
                foreach (var cross in circles[i].GetCrossPoint(circles[j]))
                {
                    if (points.All(p => p.Distance2(cross) <= r2 + e))
                    {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public static void Main()
    {
        var N = int.Parse(Console.ReadLine());
        var points = new Point[N];
        for (int i = 0; i < N; i++)
        {
            var vals = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
            points[i] = new Point(vals[0], vals[1]);
        }

        var r = 1000.0;
        r = Search(r, 0, points);
        Console.WriteLine(r);
    }
}