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 (Python):
n = int(input())
points = []
centers = []
INF = 1e100
ans = INF

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __rmul__(self, other):
        return Point(self.x * other, self.y * other)

    def __mul__(self, other):
        return Point(self.x * other, self.y * other)

    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)
        
    def __sub__(self, other):
        return Point(self.x - other.x, self.y - other.y)

    def __truediv__(self, other):
        return Point(self.x / other, self.y / other)

    def sqdist(self, other):
        return (self.x - other.x) ** 2 + (self.y - other.y) ** 2

    def dist(self, other):
        return self.sqdist(other) ** 0.5

    def cross(self, other):
        return self.x * other.y - self.y * other.x

    def dot(self, other):
        return self.x * other.x + self.y * other.y

def three(A, B, C):
    a = B.sqdist(C)
    b = C.sqdist(A)
    c = A.sqdist(B)

    U = (a*(b+c-a)*A + b*(c+a-b)*B + c*(a + b - c)*C) / (a*(b+c-a) + b*(c+a-b) + c*(a + b - c) )
    return U

for i in range(n):
    x, y = map(int, input().split())
    points.append(Point(x,y))

for i in range(n):
    for j in range(i+1, n):
        for k in range(j+1, n):
            if (points[j] - points[i]).cross(points[k] - points[i]) == 0:continue
            centers.append(three(points[i], points[j], points[k]))

for i in range(n):
    for j in range(i+1, n):
        centers.append((points[i] + points[j]) / 2)

for center in centers:
    r = 0
    for i in range(n):
        r = max(r, center.dist(points[i]))
    ans = min(ans, r)
    
print(ans)

Solution (Python):
import math
import random
from operator import itemgetter
import re
import sys
from itertools import accumulate
from collections import defaultdict
from collections import deque
from bisect import bisect_left,bisect
from heapq import heappop,heappush
from fractions import gcd
from copy import deepcopy
N = int(input())
cood = []
ans = 0
r = 0
for i in range(N):
    A= [float(i) for i in input().split()]
    cood.append(A)
for j in range(N):
    for k in range(N):
        for i in range(N):
            if i == k or i == j or j == k:
                continue
            else:
                a = cood[j][0]
                b = cood[j][1]
                c = cood[k][0]
                d = cood[k][1]
                e = cood[i][0]
                f = cood[i][1]

                aa = a * a
                bb = b * b
                cc = c * c
                dd = d * d
                ee = e * e
                ff = f * f
                if ((a-c) * (a-e) + (b-d) * (b-f)) > 0 and ((c-a) * (c-e) + (d-b) * (d-f)) > 0 and ((e-a)* (e-c) + (f-b) * (f-d)) > 0:
                    py = ((e - a) * (aa + bb - cc - dd) - (c - a) * (aa + bb - ee- ff)) / (2 * (e - a)*(b - d) - 2 * (c - a) * (b - f))

                    px = (2 * (b - f) * py - aa - bb + ee + ff) / (2 * (e - a)) \
                        if (c == a) else (2 * (b - d) * py - aa - bb + cc + dd) / (2 * (c - a))

                    r = math.hypot(px - a, py - b)
                else:
                    r = max(((a-c)**2+(b-d)**2)**(1/2),((a-e)**2+(b-f)**2)**(1/2),((e-c)**2+(f-d)**2)**(1/2))
                    r /= 2
                if r > ans:
                    ans = r
if N == 2:
    ans = ((cood[1][0]-cood[0][0])**2+(cood[1][1]-cood[0][1])**2)**(1/2)/2
print(ans)

Solution (Python):
n = int(input())
x = []
y = []
import math
for i in range(n):
    xi,yi = map(int, input().split( ))
    x.append(xi)
    y.append(yi)
if n==2:
    x.append(x[0]+10**(-8))
    y.append(y[0]+10**(-8))
import itertools
def get_circle_center_and_radius(x1, y1, x2, y2, x3, y3):
    """
    3点を通る円の中心と半径を取得
    """
    d = 2 * ((y1 - y3) * (x1 - x2) - (y1 - y2) * (x1 - x3))
    if d==0:
        return ((0,0),10**10)
    x = ((y1 - y3) * (y1 ** 2 - y2 ** 2 + x1 ** 2 - x2 ** 2) - (y1 - y2) * (y1 ** 2 - y3 ** 2 + x1 ** 2 - x3 ** 2)) / d
    y = ((x1 - x3) * (x1 ** 2 - x2 ** 2 + y1 ** 2 - y2 ** 2) - (x1 - x2) * (x1 ** 2 - x3 ** 2 + y1 ** 2 - y3 ** 2)) / -d
    r = math.sqrt((x - x1) ** 2 + (y - y1) ** 2)
    return (x, y), r
ans = 10**10
e = 10**(-8)
for i,j,k in itertools.product(range(n),range(n),range(n)):
    if i!=j and i!=k and j!=k:
        x1, y1, x2, y2, x3, y3 = x[i],y[i],x[j],y[j],x[k],y[k]
        (xc,yc),r = get_circle_center_and_radius(x1, y1, x2, y2, x3, y3)
        flag = True
        for l in range(n):
            if (x[l]-xc)**2 + (y[l]-yc)**2>r**2*(1+e):
                flag = False
                break
        if flag:
            ans = min(ans,r)


for i,j in itertools.product(range(n),range(n)):
    xc = (x[i]+x[j])/2
    yc = (y[i]+y[j])/2
    r = (x[i]-xc)**2 + (y[i]-yc)**2
    flag = True
    for l in range(n):
        if (x[l]-xc)**2 + (y[l]-yc)**2>r*(1+e):
            
            flag = False
            break
    
    if flag:
        ans = min(ans,r**(1/2))
print(ans)

Solution (Python):


import itertools
import math


EPS = 1e-6


def dot(a, b):
    return a.real * b.real + a.imag * b.imag


def enclose_triangle(p1, p2, p3):
    v12 = p2 - p1
    v23 = p3 - p2
    v31 = p1 - p3
    an1 = dot(v12, -v31)
    an2 = dot(-v12, v23)
    an3 = dot(-v23, v31)
    if an1 < 0 + EPS or an2 < 0 + EPS or an3 < 0 + EPS:
        vx = max(v12, v23, v31, key=abs)
        rad = abs(vx) / 2
        if vx == v12:
            cent = (p1 + p2) / 2
        elif vx == v23:
            cent = (p2 + p3) / 2
        else:
            cent = (p3 + p1) / 2
    else:
        a = p1
        b = p2
        c = p3
        a2 = abs(v23) ** 2
        b2 = abs(v31) ** 2
        c2 = abs(v12) ** 2
        u = a2 * (b2 + c2 - a2) * a + b2 * (c2 + a2 - b2) * \
            b + c2 * (a2 + b2 - c2) * c
        u /= a2 * (b2 + c2 - a2) + b2 * (c2 + a2 - b2) + c2 * (a2 + b2 - c2)
        rad = abs(u - p1)
        cent = u
    return rad, cent


def enclose_points(n, ps):
    assert n >= 2
    if n == 2:
        return abs(ps[1] - ps[0]) / 2
    for p1, p2, p3 in itertools.combinations(ps, 3):
        rad_cand, cent_cand = enclose_triangle(p1, p2, p3)
        for q1 in ps:
            dist = abs(cent_cand - q1)
            if dist >= rad_cand + EPS:
                break
        else:
            return rad_cand


def main():
    n = int(input())
    ps = []
    for _ in range(n):
        x, y = (float(z) for z in input().split())
        ps.append(complex(x, y))
    res = enclose_points(n, ps)
    print("{:.16f}".format(res))


if __name__ == "__main__":
    main()

Solution (Python):
import math
Point = []
 
def calcAngle(p1,p2):   
    ang = math.atan2(p2[0]-p1[0],p2[1]-p1[1])
    if(ang<0):
        ang += 2*math.pi
    return ang
 
def distance(p1,p2):
    d2 = pow(p2[0]-p1[0],2)+pow(p2[1]-p1[1],2)
    d = math.sqrt(d2)
    return d
 
def CoversM(r,N,M):
    M0 = 0
    for i in xrange(N):
        Arr = []
        for j in xrange(N):
            if(i==j): continue
            d = distance(Point[i],Point[j])
            if(d <= r*2.00):
                t0 = calcAngle(Point[i],Point[j])
                ph = math.acos(float(d)/(2.000*r))
                t1 = t0-ph+2*math.pi
                t2 = t0+ph+2*math.pi
                Arr.append((t1,1))
                Arr.append((t2,-1))
        Arr.sort(key=lambda x: x[0])
        s = 0
        for x in Arr:
            s += x[1]
            M0 = max(M0,s)
    return M0+1 >= M
 
EPS = 1e-7
def Solve(N,M):
    L,H = 0.000,1000000000
    itr = 0
    while(H > L+EPS and ++itr <= 1000):
        R = (L+H)/2.000000
        if(CoversM(R,N,M)==True):
            H = R
        else:
            L = R
    return R
 
if __name__ == "__main__":
    N = input()
    M = N
 
    for i in range(N):
        xi,yi = map(float,raw_input().split())
        Point += [(xi,yi)]
 
    print Solve(N,M)

Solution (Python):
import math, random
def make_circle(points):
    
    shuffled = [(float(p[0]), float(p[1])) for p in points]
    random.shuffle(shuffled)

    
    c = None
    for (i, p) in enumerate(shuffled):
        if c is None or not _is_in_circle(c, p):
            c = _make_circle_one_point(shuffled[0 : i + 1], p)
    return c



def _make_circle_one_point(points, p):
    c = (p[0], p[1], 0.0)
    for (i, q) in enumerate(points):
        if not _is_in_circle(c, q):
            if c[2] == 0.0:
                c = _make_diameter(p, q)
            else:
                c = _make_circle_two_points(points[0 : i + 1], p, q)
    return c



def _make_circle_two_points(points, p, q):
    diameter = _make_diameter(p, q)
    if all(_is_in_circle(diameter, r) for r in points):
        return diameter

    left = None
    right = None
    for r in points:
        cross = _cross_product(p[0], p[1], q[0], q[1], r[0], r[1])
        c = _make_circumcircle(p, q, r)
        if c is None:
            continue
        elif cross > 0.0 and (left is None or _cross_product(p[0], p[1], q[0], q[1], c[0], c[1]) > _cross_product(p[0], p[1], q[0], q[1], left[0], left[1])):
            left = c
        elif cross < 0.0 and (right is None or _cross_product(p[0], p[1], q[0], q[1], c[0], c[1]) < _cross_product(p[0], p[1], q[0], q[1], right[0], right[1])):
            right = c
    return left if (right is None or (left is not None and left[2] <= right[2])) else right


def _make_circumcircle(p0, p1, p2):
    
    ax = p0[0]; ay = p0[1]
    bx = p1[0]; by = p1[1]
    cx = p2[0]; cy = p2[1]
    d = (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by)) * 2.0
    if d == 0.0:
        return None
    x = ((ax * ax + ay * ay) * (by - cy) + (bx * bx + by * by) * (cy - ay) + (cx * cx + cy * cy) * (ay - by)) / d
    y = ((ax * ax + ay * ay) * (cx - bx) + (bx * bx + by * by) * (ax - cx) + (cx * cx + cy * cy) * (bx - ax)) / d
    return (x, y, math.hypot(x - ax, y - ay))


def _make_diameter(p0, p1):
    return ((p0[0] + p1[0]) / 2.0, (p0[1] + p1[1]) / 2.0, math.hypot(p0[0] - p1[0], p0[1] - p1[1]) / 2.0)


_EPSILON = 1e-12

def _is_in_circle(c, p):
    return c is not None and math.hypot(p[0] - c[0], p[1] - c[1]) < c[2] + _EPSILON



def _cross_product(x0, y0, x1, y1, x2, y2):
    return (x1 - x0) * (y2 - y0) - (y1 - y0) * (x2 - x0)
  
n = int(input())
p = [list(map(int, input().split())) for _ in range(n)]

print(make_circle(p)[2])

Solution (Python):
def dist(A, B):
    return ((A[0]-B[0])**2 + (A[1]-B[1])**2)**.5


def circumcenter(A, B, C):
    
    x1, y1 = B[0] - A[0], B[1] - A[1]
    x2, y2 = C[0] - A[0], C[1] - A[1]
    if abs(x1*y2 - x2*y1) < 1e-12:
        return None
    a = dist(B, C)
    b = dist(C, A)
    c = dist(A, B)
    cosA = (b**2+c**2-a**2) / (2*b*c)
    cosB = (c**2+a**2-b**2) / (2*c*a)
    cosC = (a**2+b**2-c**2) / (2*a*b)
    x = (a*cosA*A[0] + b*cosB*B[0] + c*cosC*C[0]) / (a*cosA + b*cosB + c*cosC)
    y = (a*cosA*A[1] + b*cosB*B[1] + c*cosC*C[1]) / (a*cosA + b*cosB + c*cosC)
    return x, y


N = int(input())
points = [tuple(map(int, input().split())) for i in range(N)]
if N == 2:
    print(dist(points[0], points[1]) / 2)
    exit()

ans = float('inf')

for i in range(N-1):
    for j in range(i+1, N):
        x = (points[i][0] + points[j][0]) / 2
        y = (points[i][1] + points[j][1]) / 2
        c = (x, y)
        r = dist(c, points[i])
        if r > ans:
            continue
        for point in points:
            d = dist(c, point)
            if abs(d - r) > 1e-6 and d > r:
                break
        else:
            ans = min(ans, r)

for i in range(N-2):
    for j in range(i+1, N-1):
        for k in range(j+1, N):
            c = circumcenter(points[i], points[j], points[k])
            if c is None:
                continue
            r = dist(c, points[i])
            if r > ans:
                continue
            for point in points:
                d = dist(c, point)
                if abs(d - r) > 1e-6 and d > r:
                    break
            else:
                ans = min(ans, r)
print(ans)

Solution (Python):
import random
import math
N = int(input())
XY = []
for i in range(N):
    XY.append(list(map(int,input().split())))

def make_circle(points):
	
	shuffled = [(float(x), float(y)) for (x, y) in points]
	random.shuffle(shuffled)
	
	
	c = None
	for (i, p) in enumerate(shuffled):
		if c is None or not is_in_circle(c, p):
			c = _make_circle_one_point(shuffled[ : i + 1], p)
	return c


def _make_circle_one_point(points, p):
	c = (p[0], p[1], 0.0)
	for (i, q) in enumerate(points):
		if not is_in_circle(c, q):
			if c[2] == 0.0:
				c = make_diameter(p, q)
			else:
				c = _make_circle_two_points(points[ : i + 1], p, q)
	return c


def _make_circle_two_points(points, p, q):
	circ = make_diameter(p, q)
	left  = None
	right = None
	px, py = p
	qx, qy = q
	
	
	for r in points:
		if is_in_circle(circ, r):
			continue
		
		
		cross = _cross_product(px, py, qx, qy, r[0], r[1])
		c = make_circumcircle(p, q, r)
		if c is None:
			continue
		elif cross > 0.0 and (left is None or _cross_product(px, py, qx, qy, c[0], c[1]) > _cross_product(px, py, qx, qy, left[0], left[1])):
			left = c
		elif cross < 0.0 and (right is None or _cross_product(px, py, qx, qy, c[0], c[1]) < _cross_product(px, py, qx, qy, right[0], right[1])):
			right = c
	
	
	if left is None and right is None:
		return circ
	elif left is None:
		return right
	elif right is None:
		return left
	else:
		return left if (left[2] <= right[2]) else right

def make_diameter(a, b):
	cx = (a[0] + b[0]) / 2.0
	cy = (a[1] + b[1]) / 2.0
	r0 = math.hypot(cx - a[0], cy - a[1])
	r1 = math.hypot(cx - b[0], cy - b[1])
	return (cx, cy, max(r0, r1))


def make_circumcircle(a, b, c):
	
	ox = (min(a[0], b[0], c[0]) + max(a[0], b[0], c[0])) / 2.0
	oy = (min(a[1], b[1], c[1]) + max(a[1], b[1], c[1])) / 2.0
	ax = a[0] - ox;  ay = a[1] - oy
	bx = b[0] - ox;  by = b[1] - oy
	cx = c[0] - ox;  cy = c[1] - oy
	d = (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by)) * 2.0
	if d == 0.0:
		return None
	x = ox + ((ax*ax + ay*ay) * (by - cy) + (bx*bx + by*by) * (cy - ay) + (cx*cx + cy*cy) * (ay - by)) / d
	y = oy + ((ax*ax + ay*ay) * (cx - bx) + (bx*bx + by*by) * (ax - cx) + (cx*cx + cy*cy) * (bx - ax)) / d
	ra = math.hypot(x - a[0], y - a[1])
	rb = math.hypot(x - b[0], y - b[1])
	rc = math.hypot(x - c[0], y - c[1])
	return (x, y, max(ra, rb, rc))


_MULTIPLICATIVE_EPSILON = 1 + 1e-14

def is_in_circle(c, p):
	return c is not None and math.hypot(p[0] - c[0], p[1] - c[1]) <= c[2] * _MULTIPLICATIVE_EPSILON



def _cross_product(x0, y0, x1, y1, x2, y2):
	return (x1 - x0) * (y2 - y0) - (y1 - y0) * (x2 - x0)

x = make_circle(XY)
print(x[-1])

Solution (Python):



import math
import random


_MULTIPLICATIVE_EPSILON = 1 + 1e-14


def make_circle(points):
	shuffled = [(float(x), float(y)) for (x, y) in points]
	random.shuffle(shuffled)
	c = None
	for (i, p) in enumerate(shuffled):
		if c is None or not is_in_circle(c, p):
			c = _make_circle_one_point(shuffled[ : i + 1], p)
	return c

def _make_circle_one_point(points, p):
	c = (p[0], p[1], 0.0)
	for (i, q) in enumerate(points):
		if not is_in_circle(c, q):
			if c[2] == 0.0:
				c = make_diameter(p, q)
			else:
				c = _make_circle_two_points(points[ : i + 1], p, q)
	return c

def _make_circle_two_points(points, p, q):
	circ = make_diameter(p, q)
	left  = None
	right = None
	px, py = p
	qx, qy = q
	for r in points:
		if is_in_circle(circ, r):
			continue
		cross = _cross_product(px, py, qx, qy, r[0], r[1])
		c = make_circumcircle(p, q, r)
		if c is None:
			continue
		elif cross > 0.0 and (left is None or _cross_product(px, py, qx, qy, c[0], c[1]) > _cross_product(px, py, qx, qy, left[0], left[1])):
			left = c
		elif cross < 0.0 and (right is None or _cross_product(px, py, qx, qy, c[0], c[1]) < _cross_product(px, py, qx, qy, right[0], right[1])):
			right = c
	if left is None and right is None:
		return circ
	elif left is None:
		return right
	elif right is None:
		return left
	else:
		return left if (left[2] <= right[2]) else right

def make_diameter(a, b):
	cx = (a[0] + b[0]) / 2.0
	cy = (a[1] + b[1]) / 2.0
	r0 = math.hypot(cx - a[0], cy - a[1])
	r1 = math.hypot(cx - b[0], cy - b[1])
	return (cx, cy, max(r0, r1))

def make_circumcircle(a, b, c):
	ox = (min(a[0], b[0], c[0]) + max(a[0], b[0], c[0])) / 2.0
	oy = (min(a[1], b[1], c[1]) + max(a[1], b[1], c[1])) / 2.0
	ax = a[0] - ox;  ay = a[1] - oy
	bx = b[0] - ox;  by = b[1] - oy
	cx = c[0] - ox;  cy = c[1] - oy
	d = (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by)) * 2.0
	if d == 0.0:
		return None
	x = ox + ((ax*ax + ay*ay) * (by - cy) + (bx*bx + by*by) * (cy - ay) + (cx*cx + cy*cy) * (ay - by)) / d
	y = oy + ((ax*ax + ay*ay) * (cx - bx) + (bx*bx + by*by) * (ax - cx) + (cx*cx + cy*cy) * (bx - ax)) / d
	ra = math.hypot(x - a[0], y - a[1])
	rb = math.hypot(x - b[0], y - b[1])
	rc = math.hypot(x - c[0], y - c[1])
	return (x, y, max(ra, rb, rc))

def is_in_circle(c, p):
	return c is not None and math.hypot(p[0] - c[0], p[1] - c[1]) <= c[2] * _MULTIPLICATIVE_EPSILON

def _cross_product(x0, y0, x1, y1, x2, y2):
	return (x1 - x0) * (y2 - y0) - (y1 - y0) * (x2 - x0)

N = int(input())

points = []

for n in range(N):
    x, y = map(int, input().split())
    points.append([x, y])

print(make_circle(points)[-1])

Solution (Python):
import sys
input = sys.stdin.readline

N=int(input())
P=[tuple(map(int,input().split())) for i in range(N)]

def calcdismax(x,y):
    MAX=0
    for px,py in P:
        MAX=max(MAX,(px-x)**2+(py-y)**2)

    return MAX
        
delta=10**(-10)

def div100(xmin,xmax,ymin,ymax):

    xh=(xmax-xmin)/100
    yh=(ymax-ymin)/100

    MIN=1<<30
    MINx=0
    MINy=0

    for i in range(101):
        xk=xmin+xh*i
        for j in range(101):
            yk=ymin+yh*j
            cd=calcdismax(xk,yk)

            

            if MIN>cd:
                MIN=cd
                MINx=xk
                MINy=yk

    

    return MINx,MINy

now=500
k=500
l=500
while now>10**(-7):
    k,l=div100(k-now,k+now,l-now,l+now)
    now/=2

import math
print(math.sqrt(calcdismax(k,l)))

Solution (Python):
from itertools import combinations
from math import hypot

def solve():
    INF = float('inf')
    eps = 10**-6

    N = int(input())
    pts = [tuple(map(int, input().split())) for _ in range(N)]

    if N == 2:
        x1, y1 = pts[0]
        x2, y2 = pts[1]
        ans = hypot(x1-x2, y1-y2) / 2
        print(ans)
        return

    lines = {}
    for i in range(N):
        x1, y1 = pts[i]
        for j in range(i+1, N):
            x2, y2 = pts[j]
            if y1 == y2:
                a = INF
                b = (x1+x2)/2
            else:
                x0, y0 = (x1+x2)/2, (y1+y2)/2
                a = -(x2-x1)/(y2-y1)
                b = y0 - a*x0
            lines[(i, j)] = (a, b)


    ans = INF
    for i, j, k in combinations(range(N), r=3):
        a1, b1 = lines[(i, j)]
        a2, b2 = lines[(i, k)]
        if a1 == a2: continue
        if a1 == INF:
            x = b1
            y = a2*x + b2
        elif a2 == INF:
            x = b2
            y = a1*x + b1
        else:
            x = (b2-b1) / (a1-a2)
            y = (a1*b2-b1*a2) / (a1-a2)
        x1, y1 = pts[i]
        r = hypot(x1-x, y1-y)

        for xi, yi in pts:
            dist = hypot(xi-x, yi-y)
            if dist > r + eps:
                break
        else:
            ans = min(ans, r)

    for i in range(N):
        x1, y1 = pts[i]
        for j in range(i+1, N):
            x2, y2 = pts[j]
            x, y = (x1+x2)/2, (y1+y2)/2
            r = hypot(x1-x, y1-y)
            for xi, yi in pts:
                dist = hypot(xi-x, yi-y)
                if dist > r + eps:
                    break
            else:
                ans = min(ans, r)

    print(ans)


solve()

Solution (Python):
import sys
input = sys.stdin.readline



from operator import itemgetter

def scan(Points):
    Points.sort(key=itemgetter(1))
    Points.sort(key=itemgetter(0))

    k = 0
    Qs = []
    for x, y in Points:
        while len(Qs) > 1:
            x1, y1 = Qs[-1]
            x2, y2 = Qs[-2]
            if (y1-y)*(x-x2) > (y-y2)*(x1-x):
                Qs.pop()
            else:
                break
        Qs.append((x, y))
        
    t = len(Qs)
    Qs.pop()
    for x, y in reversed(Points):
        while len(Qs) > t:
            x1, y1 = Qs[-1]
            x2, y2 = Qs[-2]
            if (y1-y)*(x-x2) > (y-y2)*(x1-x):
                Qs.pop()
            else:
                break
        Qs.append((x, y))
    Qs.pop()

    return Qs

import math

N = int(input())
XY = [list(map(int, input().split())) for _ in range(N)]

def main():
    if N == 2:
        x1, y1 = XY[0]
        x2, y2 = XY[1]
        d = math.sqrt((x1-x2)**2+(y1-y2)**2)
        print(d/2)
        return
    outerpoints = scan(XY)

    min2 = 10**16
    for i in range(N-1):
        for j in range(i+1, N):
            x1, y1 = XY[i]
            x2, y2 = XY[j]
            px, py = (x1+x2)/2, (y1+y2)/2
            r = math.sqrt((px-x1)**2+(py-y1)**2)
            using = [(x1, y1), (x2, y2)]
            ok = True
            for ox, oy in outerpoints:
                if (ox, oy) in using:
                    continue
                if math.sqrt((ox-px)**2+(oy-py)**2) > r:
                    ok = False
                    break
            if ok:
                min2 = min(min2, r)
    
                
    min3 = 10**16
    for i in range(N-2):
        for j in range(i+1, N-1):
            for k in range(j+1, N):
                a, b = XY[i]
                c, d = XY[j]
                e, f = XY[k]
                if (2*(e-a)*(b-d)-2*(c-a)*(b-f)) == 0:
                    px = (max([a, c, e])+min([a, c, e]))/2
                    py = (max([b, d, f])+min([b, d, f]))/2
                else:
                    py = ((e-a)*(a**2+b**2-c**2-d**2) - (c-a)*(a**2+b**2-e**2-f**2)) / (2*(e-a)*(b-d)-2*(c-a)*(b-f))
                    if c != a:
                        px = (2*(b-d)*py-a**2-b**2+c**2+d**2)/(2*(c-a))
                    else:
                        px = (2*(b-f)*py-a**2-b**2+e**2+f**2)/(2*(e-a))
                r = math.sqrt((px-a)**2+(py-b)**2)
                using = [(a, b), (c, d), (e, f)]
                ok = True
                for ox, oy in outerpoints:
                    if (ox, oy) in using:
                        continue
                    if math.sqrt((ox-px)**2+(oy-py)**2) > r:
                        ok = False
                        break
                if ok:
                    min3 = min(min3, r)
    print(min(min2, min3))
    return


if __name__ == "__main__":
    main()

Solution (Python):























import math, random










def make_circle(points):
    
    shuffled = [(float(p[0]), float(p[1])) for p in points]
    random.shuffle(shuffled)

    
    c = None
    for (i, p) in enumerate(shuffled):
        if c is None or not _is_in_circle(c, p):
            c = _make_circle_one_point(shuffled[0 : i + 1], p)
    return c



def _make_circle_one_point(points, p):
    c = (p[0], p[1], 0.0)
    for (i, q) in enumerate(points):
        if not _is_in_circle(c, q):
            if c[2] == 0.0:
                c = _make_diameter(p, q)
            else:
                c = _make_circle_two_points(points[0 : i + 1], p, q)
    return c



def _make_circle_two_points(points, p, q):
    diameter = _make_diameter(p, q)
    if all(_is_in_circle(diameter, r) for r in points):
        return diameter

    left = None
    right = None
    for r in points:
        cross = _cross_product(p[0], p[1], q[0], q[1], r[0], r[1])
        c = _make_circumcircle(p, q, r)
        if c is None:
            continue
        elif cross > 0.0 and (left is None or _cross_product(p[0], p[1], q[0], q[1], c[0], c[1]) > _cross_product(p[0], p[1], q[0], q[1], left[0], left[1])):
            left = c
        elif cross < 0.0 and (right is None or _cross_product(p[0], p[1], q[0], q[1], c[0], c[1]) < _cross_product(p[0], p[1], q[0], q[1], right[0], right[1])):
            right = c
    return left if (right is None or (left is not None and left[2] <= right[2])) else right


def _make_circumcircle(p0, p1, p2):
    
    ax = p0[0]; ay = p0[1]
    bx = p1[0]; by = p1[1]
    cx = p2[0]; cy = p2[1]
    d = (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by)) * 2.0
    if d == 0.0:
        return None
    x = ((ax * ax + ay * ay) * (by - cy) + (bx * bx + by * by) * (cy - ay) + (cx * cx + cy * cy) * (ay - by)) / d
    y = ((ax * ax + ay * ay) * (cx - bx) + (bx * bx + by * by) * (ax - cx) + (cx * cx + cy * cy) * (bx - ax)) / d
    return (x, y, math.hypot(x - ax, y - ay))


def _make_diameter(p0, p1):
    return ((p0[0] + p1[0]) / 2.0, (p0[1] + p1[1]) / 2.0, math.hypot(p0[0] - p1[0], p0[1] - p1[1]) / 2.0)


_EPSILON = 1e-12

def _is_in_circle(c, p):
    return c is not None and math.hypot(p[0] - c[0], p[1] - c[1]) < c[2] + _EPSILON



def _cross_product(x0, y0, x1, y1, x2, y2):
    return (x1 - x0) * (y2 - y0) - (y1 - y0) * (x2 - x0)
  
points= [(421640.3639270504, 4596366.353552659), (421635.79361391126, 4596369.054192241), (421632.6774913164, 4596371.131607305), (421629.14588570886, 4596374.870954419), (421625.6142801013, 4596377.779335507), (421624.99105558236, 4596382.14190714), (421630.1845932406, 4596388.062540068), (421633.3007158355, 4596388.270281575), (421637.87102897465, 4596391.8018871825), (421642.4413421138, 4596394.918009778), (421646.5961722403, 4596399.903805929), (421649.71229483513, 4596403.850894549), (421653.8940752105, 4596409.600842565), (421654.69809098693, 4596410.706364258), (421657.60647207545, 4596411.329588776), (421660.514853164, 4596409.875398233), (421661.3458191893, 4596406.136051118), (421661.5535606956, 4596403.22767003), (421658.85292111343, 4596400.94251346), (421656.5677645438, 4596399.696064423), (421655.52905701223, 4596396.164458815), (421652.82841743, 4596394.502526765), (421648.46584579715, 4596391.8018871825), (421646.38843073393, 4596388.270281575), (421645.55746470863, 4596386.400608018), (421647.21939675923, 4596384.115451449), (421649.5045533288, 4596382.661260904), (421650.7510023668, 4596378.714172284), (421647.8426212782, 4596375.8057911955), (421644.9342401897, 4596372.897410107), (421643.6877911517, 4596370.404512031), (421640.3639270504, 4596366.353552659)]
pointss=[]
n=int(input()
     )
for i in range(n):
  x,y=map(int,input().split())
  
  pointss.append((x,y))

ans=make_circle(pointss)
print(ans[2])