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 Rust (1.42.0) (judge verdict: Accepted)

#![allow(unused_imports)]
use {
   proconio::{fastout, input, marker::*},
   std::cmp::*,
   std::collections::*,
};

fn main() {
   input! {
      n:usize,
      xy: [(i64, i64); n]
   }

   let mut low = 0f64;
   let mut high = 1000f64;
   let mut pm = vec![];
   for i in 0..n {
      for j in i + 1..n {
         let (x1, y1) = xy[i];
         let (x2, y2) = xy[j];
         pm.push(((x1 + x2) as f64 / 2.0, (y1 + y2) as f64 / 2.0));
      }
   }

   for &(x1, y1) in pm.iter() {
      let mut mx = 0f64;
      for (x2, y2) in xy.iter().map(|&(x, y)| (x as f64, y as f64)) {
         let r = ((x1 - x2).powi(2) + (y1 - y2).powi(2)).sqrt();
         if mx < r {
            mx = r;
         }
      }
      if mx < high {
         high = mx;
      }
   }

   'outer: for _ in 0..100 {
      let r = (high + low) / 2.0;
      let mut points = pm.clone();
      for i in 0..n - 1 {
         for j in i + 1..n {
            if let Some((p1, p2)) = intersection(r, xy[i], xy[j]) {
               points.push(p1);
               points.push(p2);
            } else {
               low = r;
               continue 'outer;
            }
         }
      }
      let mut flag = false;
      let mut rm = 0f64;
      'outer1: for (x1, y1) in points {
         for (x2, y2) in xy.iter().map(|&(x, y)| (x as f64, y as f64)) {
            let rn = ((x1 - x2).powi(2) + (y1 - y2).powi(2)).sqrt();
            if rn > r {
               continue 'outer1;
            }
            if rn > rm {
               rm = rn;
            }
         }
         flag = true;
         break;
      }
      if flag {
         high = rm;
      } else {
         low = r;
      }
   }
   println!("{0:.10}", high);
}

fn intersection(
   r: f64,
   (x1, y1): (i64, i64),
   (x2, y2): (i64, i64),
) -> Option<((f64, f64), (f64, f64))> {
   let mx = (x1 + x2) as f64 / 2.0;
   let my = (y1 + y2) as f64 / 2.0;
   let dx = (x1 - x2) as f64;
   let dy = (y1 - y2) as f64;
   let dr = (dx * dx + dy * dy).sqrt();
   if dr <= 2.0 * r {
      let h = (r * r - dr * dr / 4.0).sqrt();
      let a = (-dx / dy).atan();
      return Some((
         (mx + h * a.cos(), my + h * a.sin()),
         (mx - h * a.cos(), my - h * a.sin()),
      ));
   }
   None
}