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 Go (1.6) (judge verdict: Accepted)

package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"sort"
	"strconv"
)

func getScanner(fp *os.File) *bufio.Scanner {
	scanner := bufio.NewScanner(fp)
	scanner.Split(bufio.ScanWords)
	scanner.Buffer(make([]byte, 500001), 500000)
	return scanner
}

func getNextString(scanner *bufio.Scanner) string {
	scanner.Scan()
	return scanner.Text()
}

func getNextInt(scanner *bufio.Scanner) int {
	i, _ := strconv.Atoi(getNextString(scanner))
	return i
}

func getNextInt64(scanner *bufio.Scanner) int64 {
	i, _ := strconv.ParseInt(getNextString(scanner), 10, 64)
	return i
}

func getNextUint64(scanner *bufio.Scanner) uint64 {
	i, _ := strconv.ParseUint(getNextString(scanner), 10, 64)
	return i
}

func getNextFloat64(scanner *bufio.Scanner) float64 {
	i, _ := strconv.ParseFloat(getNextString(scanner), 64)
	return i
}

func main() {
	fp := os.Stdin
	wfp := os.Stdout
	cnt := 0

	if os.Getenv("MASPY") == "ますピ" {
		fp, _ = os.Open(os.Getenv("BEET_THE_HARMONY_OF_PERFECT"))
		cnt = 6
	}
	if os.Getenv("MASPYPY") == "ますピッピ" {
		wfp, _ = os.Create(os.Getenv("NGTKANA_IS_GENIUS10"))
	}

	scanner := getScanner(fp)
	writer := bufio.NewWriter(wfp)
	solve(scanner, writer)
	for i := 0; i < cnt; i++ {
		fmt.Fprintln(writer, "-----------------------------------")
		solve(scanner, writer)
	}
	writer.Flush()
}

func solve(scanner *bufio.Scanner, writer *bufio.Writer) {
	n := getNextInt(scanner)
	pp := make(PP, n)
	rp := Point{
		x: 0.0,
		y: 0.0,
	}
	for i := 0; i < n; i++ {
		pp[i].x = getNextFloat64(scanner)
		pp[i].y = getNextFloat64(scanner)
		pp[i].rp = &rp
	}
	first := -1
	max := 0.0
	for i := 0; i < n; i++ {
		dist := math.Pow(pp[i].x, 2) + math.Pow(pp[i].y, 2)
		if max < dist {
			first = i
			max = dist
		}
	}
	lp := Point{
		x: pp[first].x,
		y: pp[first].y,
	}
	for i := 0; i < 60; i++ {
		mx := (lp.x + rp.x) / 2.0
		my := (lp.y + rp.y) / 2.0
		r := math.Pow(pp[first].x-mx, 2) + math.Pow(pp[first].y-my, 2)
		valid := true
		for j := 0; j < n && valid; j++ {
			valid = r+1e-7 >= math.Pow(pp[j].x-mx, 2)+math.Pow(pp[j].y-my, 2)
		}
		if valid {
			rp.x = mx
			rp.y = my
			continue
		}
		lp.x = mx
		lp.y = my
	}
	second := -1
	max = 0.0
	for i := 0; i < n; i++ {
		if i == first {
			continue
		}
		dist := math.Pow(pp[i].x-rp.x, 2) + math.Pow(pp[i].y-rp.y, 2)
		if max < dist {
			second = i
			max = dist
		}
	}

	lp = Point{
		x: (pp[first].x + pp[second].x) / 2.0,
		y: (pp[first].y + pp[second].y) / 2.0,
	}

	for i := 0; i < 60; i++ {
		mx := (lp.x + rp.x) / 2.0
		my := (lp.y + rp.y) / 2.0
		r := math.Pow(pp[first].x-mx, 2) + math.Pow(pp[first].y-my, 2)
		valid := true
		for j := 0; j < n && valid; j++ {
			valid = r+1e-7 >= math.Pow(pp[j].x-mx, 2)+math.Pow(pp[j].y-my, 2)
		}
		if valid {
			rp.x = mx
			rp.y = my
			continue
		}
		lp.x = mx
		lp.y = my
	}

	for k := 0; n >= 3 && k < n*2; k++ {
		sort.Sort(pp)
		l1 := math.Pow(pp[0].x-pp[1].x, 2) + math.Pow(pp[0].y-pp[1].y, 2)
		l2 := math.Pow(pp[0].x-pp[2].x, 2) + math.Pow(pp[0].y-pp[2].y, 2)
		l3 := math.Pow(pp[1].x-pp[2].x, 2) + math.Pow(pp[1].y-pp[2].y, 2)
		first = 0
		second = 1
		if l1 < l2 {
			first = 0
			second = 2
			l1 = l2
		}
		if l1 < l3 {
			first = 1
			second = 2
		}

		lp = Point{
			x: (pp[first].x + pp[second].x) / 2.0,
			y: (pp[first].y + pp[second].y) / 2.0,
		}

		for i := 0; i < 100; i++ {
			mx := (lp.x + rp.x) / 2.0
			my := (lp.y + rp.y) / 2.0
			r := math.Pow(pp[first].x-mx, 2) + math.Pow(pp[first].y-my, 2)
			valid := true
			for j := 0; j < n && valid; j++ {
				valid = r+1e-7 >= math.Pow(pp[j].x-mx, 2)+math.Pow(pp[j].y-my, 2)
			}
			if valid {
				rp.x = mx
				rp.y = my
				continue
			}
			lp.x = mx
			lp.y = my
		}
	}
	sort.Sort(pp)

	ans := math.Pow(pp[0].x-rp.x, 2) + math.Pow(pp[0].y-rp.y, 2)

	fmt.Fprintln(writer, math.Sqrt(ans))
}

// Point ...
type Point struct {
	x, y float64
	rp   *Point
}

type PP []Point

func (a PP) Len() int      { return len(a) }
func (a PP) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a PP) Less(i, j int) bool {
	return math.Pow(a[i].x-a[i].rp.x, 2)+math.Pow(a[i].y-a[i].rp.y, 2) > math.Pow(a[j].x-a[j].rp.x, 2)+math.Pow(a[j].y-a[j].rp.y, 2)
}