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 PyPy3 (2.4.0) (judge verdict: Accepted)

import math
import itertools
import sys
sys.setrecursionlimit(20000)


def gcd(a, b):
    a, b = abs(a), abs(b)
    a, b = max(a, b), min(a, b)
    while b > 0:
        tmp = b
        b = a % b
        a = tmp
        a, b = max(a, b), min(a, b)
    return a


def dist(p, q):
    return math.sqrt((p[0] - q[0]) ** 2 +
                     (p[1] - q[1]) ** 2)


def is_liner(a, b, c):
    x = (b[0] - a[0], b[1] - a[1])
    y = (c[0] - a[0], c[1] - a[1])
    gcdx = gcd(x[0], x[1])
    x = (x[0] // gcdx, x[1] // gcdx)
    gcdy = gcd(y[0], y[1])
    y = (y[0] // gcdy, y[1] // gcdy)
    return x == y


def angle(a, b, c):
    p = (b[0] - a[0], b[1] - a[1])
    q = (c[0] - a[0], c[1] - a[1])
    ang = abs(math.atan2(p[1], p[0]) - math.atan2(q[1], q[0]))
    return min(ang, math.pi * 2 - ang)


def outer_soul(a, b, c):
    A = angle(a, b, c)
    B = angle(b, c, a)
    C = angle(c, a, b)
    s2A = math.sin(2*A)
    s2B = math.sin(2*B)
    s2C = math.sin(2*C)
    o = [0] * 2
    for i in range(2):
        o[i] = (s2A * a[i] + s2B * b[i] + s2C * c[i]) / (s2A + s2B + s2C)
    return o


def check(o, r, P):
    for p in P:
        if dist(o, p) > r + 1e-6:
            return False
    return True


def main():
    N = int(input())
    P = [None] * N
    for i in range(N):
        x, y = map(int, input().split())
        P[i] = (x, y)
    ans = float("inf")
    for a, b, c in itertools.combinations(P, r=3):
        if is_liner(a, b, c):
            continue
        o = outer_soul(a, b, c)
        r = dist(a, o)
        if check(o, r, P):
            ans = min(ans, r)
    for a, b in itertools.combinations(P, r=2):
        o = ((a[0] + b[0]) / 2, (a[1] + b[1]) / 2)
        r = dist(a, b) / 2
        if check(o, r, P):
            ans = min(ans, r)
    print(ans)


if __name__ == "__main__":
    main()