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 (
  "fmt"
  "math"
  "sort"
)

func main() {
  var n int
  fmt.Scan(&n)
  p := Points{}
  for i:=0;i<n;i++ {
    var x,y float64
    fmt.Scan(&x,&y)
    p = append(p,Point{x,y,i})
  }
  h := p.GetHull()
  if h.Len() == 1 {
    fmt.Println(0)
    return
  } else if h.Len() == 2 {
    fmt.Println(0.5*h[0].distance(h[1]))
    return
  }
  ans := 1e18
  for _,p0 := range h {
    for _,p1 := range h {
      if p1 == p0 { continue }
      for _,p2 := range h {
        if p2 == p0 || p2 == p1 { continue }
        var x,y float64
        a0 := p0.angle(p2,p1)
        if a0 < 0.0 { a0 += 2*math.Pi }
        a1 := p1.angle(p0,p2)
        if a1 < 0.0 { a1 += 2*math.Pi }
        a2 := p2.angle(p1,p0)
        if a2 < 0.0 { a2 += 2*math.Pi }
        if a0 >= 0.5*math.Pi {
          x = 0.5*(p1.x+p2.x)
          y = 0.5*(p1.y+p2.y)
        } else if a1 >= 0.5*math.Pi {
          x = 0.5*(p2.x+p0.x)
          y = 0.5*(p2.y+p0.y)
        } else if a2 >= 0.5*math.Pi {
          x = 0.5*(p0.x+p1.x)
          y = 0.5*(p0.y+p1.y)
        } else {
          a := p1.distance2(p2)
          b := p2.distance2(p0)
          c := p0.distance2(p1)
          A := a*(b+c-a)
          B := b*(c+a-b)
          C := c*(a+b-c)
          x = (A*p0.x+B*p1.x+C*p2.x)/(A+B+C)
          y = (A*p0.y+B*p1.y+C*p2.y)/(A+B+C)
        }
        p := Point{x,y,-1}
        r := 0.0
        for _,q := range h { r = math.Max(r,p.distance(q)) }
        ans = math.Min(ans,r)
      }
    }
  }
  fmt.Printf("%.20f\n",ans)
}

type Point struct {
  x,y float64
  id int
}
func(p Point) equals(t Point) bool { return p.x == t.x && p.y == t.y }
func(p Point) angle(sta Point,end Point) float64 {
  ax := sta.x - p.x
  bx := end.x - p.x
  ay := sta.y - p.y
  by := end.y - p.y
  return math.Atan2(ax*by-ay*bx,ax*bx+ay*by)
}
func(p Point) distance2(t Point) float64 {
  dx := p.x - t.x
  dy := p.y - t.y
  return dx*dx+dy*dy
}
func(p Point) distance(t Point) float64 {
  return math.Sqrt(p.distance2(t))
}
type Points []Point
func(ps Points) Len() int { return len(ps) }
func(ps Points) Swap(i,j int) { ps[i],ps[j] = ps[j],ps[i] }
func(ps Points) Less(i,j int) bool {
  if ps[i].x == ps[j].x {
    if ps[i].y == ps[j].y { return ps[i].id < ps[j].id }
    return ps[i].y < ps[j].y
  }
  return ps[i].x < ps[j].x
}
func(ps Points) GetHull() Points {
  sort.Sort(sort.Reverse(ps))
  now := ps[0]
  prv := Point{now.x,now.y-1,-1}
  hull := Points{now}
  for {
    var minagl,maxdst float64
    minagl = 2*math.Pi
    maxdst = 0
    nxt := ps[0]
    for _,p := range ps {
      if p.equals(now) { continue }
      var angle,dstnc float64
      angle = now.angle(prv,p)
      dstnc = now.distance(p)
      if angle < 0 { angle += 2*math.Pi }
      if angle < minagl && angle >= math.Pi {
        minagl = angle
        nxt = p
        maxdst = dstnc
      } else if angle == minagl && dstnc > maxdst {
        nxt = p
        maxdst = dstnc
      }
    }
    if nxt.equals(hull[0]) { break }
    hull = append(hull,nxt)
    prv = now
    now = nxt
  }
  return hull
}