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.15.1) (judge verdict: Wrong Answer)

#[allow(unused_imports)]
use std::cmp::{Ordering};

#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};

#[allow(unused_imports)]
use std::io::{stdin, stdout, BufWriter, Write};

#[allow(unused_imports)]
use std::iter::FromIterator;

#[allow(unused_macros)]
macro_rules! min {
    ($x: expr) => ($x);
    ($x: expr, $($z: expr),+) => {{
        std::cmp::min($x, min!($($z),*))
    }}
}

#[allow(unused_macros)]
macro_rules! max {
    ($x: expr) => ($x);
    ($x: expr, $($z: expr),+) => {{
        std::cmp::max($x, max!($($z),*))
    }}
}

#[allow(unused_macros)]
macro_rules! get { 
    ([$t: ty]) => { 
        { 
            let mut line = String::new(); 
            stdin().read_line(&mut line).unwrap(); 
            line.split_whitespace().map(|t|t.parse::<$t>().unwrap()).collect::<Vec<_>>()
        }
    };
    ([$t: ty];$n: expr) => {
        (0..$n).map(|_|get!([$t])).collect::<Vec<_>>()
    };
    ($t: ty) => {
        {
            let mut line = String::new();
            stdin().read_line(&mut line).unwrap();
            line.trim().parse::<$t>().unwrap()
        }
    };
    ($($t: ty),*) => {
        { 
            let mut line = String::new();
            stdin().read_line(&mut line).unwrap();
            let mut iter = line.split_whitespace();
            ($(iter.next().unwrap().parse::<$t>().unwrap(),)*)
        }
    };
    ($t: ty; $n: expr) => {
        (0..$n).map(|_|get!($t)).collect::<Vec<_>>()
    };
    ($($t: ty),*; $n: expr) => {
        (0..$n).map(|_|get!($($t),*)).collect::<Vec<_>>()
    };
}

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        #[cfg(debug_assertions)]
        writeln!(&mut std::io::stderr(), concat!("[DEBUG] ", $(stringify!($a), "={:?} "),*), $($a),*).unwrap();
    }
}

const BIG_STACK_SIZE: bool = true;

#[allow(dead_code)]
fn main() {
    use std::thread;
    if BIG_STACK_SIZE {
        thread::Builder::new()
            .stack_size(32 * 1024 * 1024)
            .name("solve".into())
            .spawn(solve)
            .unwrap()
            .join()
            .unwrap();
    } else {
        solve();
    }
}

fn lower_bound<F>(l: f64, r: f64, criterion: F) -> f64
where
    F: Fn(f64) -> bool,
{
    let mut l = l;
    let mut r = r;
    let epsilon = 1e-7;
    while r - l > epsilon {
        let mid = (l+r)/2.0;
        if criterion(mid) {
            r = mid;
        } else {
            l = mid;
        }
    }
    l
}

fn solve() {
    let n = get!(usize);
    let xy = get!(isize, isize; n);

    let mut mx = 0;
    for i in 0..n {
        for j in 0..n {
            mx = max!(mx, (xy[i].0-xy[j].0).pow(2)+(xy[i].1-xy[j].1).pow(2));
        }
    }
    let min_radius =  (mx as f64).sqrt()/2.0;
    let mut mn = std::f64::MAX;
    for i in 0..n {
        for j in 0..n {
            if i == j {
                continue;
            }
            let d = (((xy[i].0-xy[j].0).pow(2)+(xy[i].1-xy[j].1).pow(2)) as f64).sqrt();
            let vec = ((xy[i].0-xy[j].0) as f64, (xy[i].1-xy[j].1) as f64);
            let mid = (xy[j].0 as f64+vec.0/2.0, xy[j].1 as f64+vec.1/2.0);
            let nom = [(vec.1/d, -vec.0/d), (-vec.1/d, vec.0/d)];
            let crit = |radius: f64| {
                let tmp = radius*radius-d*d/4.0;
                if tmp < 0.0 {
                    return false;
                }
                let len = tmp.sqrt();
                for k in 0..2 {
                    let center = (mid.0 + nom[k].0*len, mid.1 + nom[k].1*len);
                    let mut flag = false;
                    for l in 0..n {
                        if i==l || j==l {
                            continue;
                        }
                        let dist2 = (center.0-xy[l].0 as f64).powf(2.0) + (center.1-xy[l].1 as f64).powf(2.0);
                        if dist2 > radius*radius {
                            flag = true;
                            break;
                        }
                    }
                    if !flag {
                        return true;
                    }
                }
                false
            };
            let res = lower_bound(0.0, 1500.0, crit);
            mn = mn.min(res);
        }
    }
    println!("{}", mn);
}