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 Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Main main = new Main();
        main.solve();
    }
    public void solve() {
        Scanner scan = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
        int N = scan.nextInt();
        double[] x = new double[N];
        double[] y = new double[N];
        for (int i = 0; i < N; i++) {
            x[i] = scan.nextDouble();
            y[i] = scan.nextDouble();
        }
        if (N == 2) {
            System.out.printf("%.9f\n", distance(x[0],y[0],x[1],y[1])/2);
            return;
        }
        boolean found = false;
        for (int i = 2; i < N; i++) {
            if (!is_line(x[0],y[0],x[1],y[1],x[i],y[i])) {
                found = true;
                break;
            }
        }
        if (!found) {
            double answer = Double.MAX_VALUE;
            for (int i = 0; i < N; i++) {
                for (int j = i + 1; j < N; j++) {
                    double[] center = new double[2];
                    center[0] = (x[i]+x[j])/2;
                    center[1] = (y[i]+y[j])/2;
                    double max_distance = 0;
                    for (int p = 0; p < N; p++) {
                        max_distance = Math.max(max_distance, distance(center[0],center[1], x[p], y[p]));
                    }
                    answer = Math.min(answer, max_distance);
                }
            }
            System.out.printf("%.9f\n", answer);
            return;
        }
        double answer = Double.MAX_VALUE;
        for (int i = 0; i < N; i++) {
            for (int j = i + 1; j < N; j++) {
                for (int k = j + 1; k < N; k++) {
                    double[] center = null;
                    if (is_line(x[i],y[i],x[j],y[j],x[k],y[k])) {
                        continue;
                    }
                    center = center_distance_tri(x[i],y[i], x[j],y[j], x[k], y[k]);
                    double max_distance = 0;
                    for (int p = 0; p < N; p++) {
                        max_distance = Math.max(max_distance, distance(center[0],center[1], x[p], y[p]));
                    }
                    answer = Math.min(answer, max_distance);
                }
            }
        }
        for (int i = 0; i < N; i++) {
            for (int j = i + 1; j < N; j++) {
                double[] center = new double[2];
                center[0] = (x[i]+x[j])/2;
                center[1] = (y[i]+y[j])/2;
                double max_distance = 0;
                for (int p = 0; p < N; p++) {
                    max_distance = Math.max(max_distance, distance(center[0],center[1], x[p], y[p]));
                }
                answer = Math.min(answer, max_distance);
            }
        }
        System.out.printf("%.9f\n", answer);
    }
    private boolean is_line(double x1, double y1, double x2, double y2, double x3, double y3) {
        double dx1 = x2 - x1;
        double dy1 = y2 - y1;
        double dx2 = x3 - x1;
        double dy2 = y3 - y1;
        return dx1 * dy2 == dx2 * dy1;
    }
    private double[] center_distance_tri(double a, double b, double c, double d, double e, double f) {
        double py = ((e-a) * (a*a + b*b - c*c - d*d) - (c-a)*(a*a + b*b - e*e - f*f))/(2*(e-a)*(b-d)-2*(c-a)*(b-f));
        double px = 0;
        if (c-a == 0) {
            px = (2*(b-f)*py - a*a - b*b + e*e + f*f) / (2*(e-a));
        } else {
            px = (2*(b-f)*py - a*a - b*b + e*e + f*f) / (2*(c-a));
        }
        double[] p = new double[2];
        p[0] = px;
        p[1] = py;
        return p;
    }
    private double[] center_distance_line(double x1, double y1, double x2, double y2, double x3, double y3) {
        double temp1 = distance(x1, y1, x2, y2);
        double temp2 = distance(x1, y1, x3, y3);
        double temp3 = distance(x2, y2, x3, y3);
        double[] p = new double[2];
        p[0] = (x1 + x2)/2;
        p[1] = (y1 + y2)/2;
        double temp = temp1;
        if (temp < temp2) {
            temp = temp2;
            p[0] = (x1 + x3)/2;
            p[1] = (y1 + y3)/2;
        }
        if (temp < temp3) {
            p[0] = (x2 + x3)/2;
            p[1] = (y2 + y3)/2;
        }
        return p;
    }
    private double distance(double x1, double y1, double x2, double y2) {
        double z = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
        return Math.sqrt(z);
    }
}