Problem:
Score : 600 points

Problem Statement

Takahashi wants to grill N pieces of meat on a grilling net, which can be seen as a two-dimensional plane. The coordinates of the i-th piece of meat are \left(x_i, y_i\right), and its hardness is c_i.

Takahashi can use one heat source to grill the meat. If he puts the heat source at coordinates \left(X, Y\right), where X and Y are real numbers, the i-th piece of meat will be ready to eat in c_i \times \sqrt{\left(X - x_i\right)^2 + \left(Y-y_i\right)^2} seconds.

Takahashi wants to eat K pieces of meat. Find the time required to have K or more pieces of meat ready if he put the heat source to minimize this time.

Constraints

All values in input are integers.

1 \leq N \leq 60

1 \leq K \leq N

-1000 \leq x_i , y_i \leq 1000

\left(x_i, y_i\right) \neq \left(x_j, y_j\right) \left(i \neq j \right)

1 \leq c_i \leq 100

Input

Input is given from Standard Input in the following format:

N K
x_1 y_1 c_1
\vdots
x_N y_N c_N

Output

Print the answer.

It will be considered correct if its absolute or relative error from our answer is at most 10^{-6}.

Sample Input 1

4 3
-1 0 3
0 0 3
1 0 2
1 1 40

Sample Output 1

2.4

If we put the heat source at \left(-0.2, 0\right), the 1-st, 2-nd, and 3-rd pieces of meat will be ready to eat within 2.4 seconds. This is the optimal place to put the heat source.

Sample Input 2

10 5
-879 981 26
890 -406 81
512 859 97
362 -955 25
128 553 17
-885 763 2
449 310 57
-656 -204 11
-270 76 40
184 170 16

Sample Output 2

7411.2252

Solution in Rust (1.15.1) (judge verdict: Accepted)

macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        let mut next = || { iter.next().unwrap() };
        input_inner!{next, $($r)*}
    };
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String {
            bytes
                .by_ref()
                .map(|r| r.unwrap() as char)
                .skip_while(|c| c.is_whitespace())
                .take_while(|c| !c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };

    ($next:expr, mut $var:ident : $t:tt $($r:tt)*) => {
        let mut $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };

    ($next:expr, [ $t:tt ]) => {
        {
            let len = read_value!($next, usize);
            (0..len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
        }
    };

    ($next:expr, chars) => {
        read_value!($next, String).chars().collect::<Vec<char>>()
    };

    ($next:expr, usize1) => {
        read_value!($next, usize) - 1
    };

    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}

#[allow(unused_imports)]
use std::cmp::{min, max};

fn main() {
    input!{
        n: usize,
        k: usize,
        v: [(f64, f64, f64); n]
    }
    let mut ans: f64 = 1000000.0;
    for &(cx, cy, _) in &v {
        ans = ans.min(test(cx, cy, k, &v));
    }
    for i in 0..n {
        for j in i + 1..n {
            let cx = (v[i].2 * v[i].0 + v[j].2 * v[j].0) / (v[i].2 + v[j].2);
            let cy = (v[i].2 * v[i].1 + v[j].2 * v[j].1) / (v[i].2 + v[j].2);
            ans = ans.min(test(cx, cy, k, &v));
        }
    }
    for i in 0..n {
        for j in i + 1..n {
            for l in j + 1..n {
                if v[i].2 == v[j].2 && v[i].2 == v[l].2 {
                    let ((cx, cy), r2) = circumcenter((v[i].0, v[i].1), (v[j].0, v[j].1), (v[l].0, v[l].1));
                    if r2 < 0.0 {
                        continue;
                    }
                    ans = ans.min(test(cx, cy, k, &v));
                } else if v[i].2 == v[j].2 || v[i].2 == v[l].2 {
                    let (x1, y1, x2, y2, c2) = if v[i].2 == v[j].2 {
                        (v[j].0, v[j].1, v[l].0, v[l].1, v[l].2)
                    } else {
                        (v[l].0, v[l].1, v[j].0, v[j].1, v[j].2)
                    };
                    let d = dist2((x1, y1), (v[i].0, v[i].1));
                    let a = d / 2.0 - ((x1 - v[i].0) * (x2 - v[i].0) + (y1 - v[i].1) * (y2 - v[i].1)) * c2.powi(2) / (c2.powi(2) - v[i].2.powi(2));
                    let r = dist2((x2, y2), (v[i].0, v[i].1)) * v[i].2.powi(2) * c2.powi(2) / (c2.powi(2) - v[i].2.powi(2)).powi(2);
                    if d * r < a.powi(2) {
                        continue;
                    }
                    let cx = ((x1 - v[i].0) * a + (y1 - v[i].1) * (d * r - a.powi(2)).sqrt()) / d + (x2 - v[i].0) * c2.powi(2) / (c2.powi(2) - v[i].2.powi(2)) + v[i].0;
                    let cy = ((y1 - v[i].1) * a - (x1 - v[i].0) * (d * r - a.powi(2)).sqrt()) / d + (y2 - v[i].1) * c2.powi(2) / (c2.powi(2) - v[i].2.powi(2)) + v[i].1;
                    ans = ans.min(test(cx, cy, k, &v));
                    let cx = ((x1 - v[i].0) * a - (y1 - v[i].1) * (d * r - a.powi(2)).sqrt()) / d + (x2 - v[i].0) * c2.powi(2) / (c2.powi(2) - v[i].2.powi(2)) + v[i].0;
                    let cy = ((y1 - v[i].1) * a + (x1 - v[i].0) * (d * r - a.powi(2)).sqrt()) / d + (y2 - v[i].1) * c2.powi(2) / (c2.powi(2) - v[i].2.powi(2)) + v[i].1;
                    ans = ans.min(test(cx, cy, k, &v));
                } else {
                    let px = v[j].0 - v[i].0;
                    let py = v[j].1 - v[i].1;
                    let qx = v[l].0 - v[i].0;
                    let qy = v[l].1 - v[i].1;
                    let x0 = px * v[j].2.powi(2) / (v[j].2.powi(2) - v[i].2.powi(2)) + v[i].0;
                    let y0 = py * v[j].2.powi(2) / (v[j].2.powi(2) - v[i].2.powi(2)) + v[i].1;
                    let x1 = qx * v[l].2.powi(2) / (v[l].2.powi(2) - v[i].2.powi(2)) + v[i].0;
                    let y1 = qy * v[l].2.powi(2) / (v[l].2.powi(2) - v[i].2.powi(2)) + v[i].1;
                    let r0 = dist2((px, py), (0.0, 0.0)) * v[j].2.powi(2) * v[i].2.powi(2) / (v[j].2.powi(2) - v[i].2.powi(2)).powi(2);
                    let r1 = dist2((qx, qy), (0.0, 0.0)) * v[l].2.powi(2) * v[i].2.powi(2) / (v[l].2.powi(2) - v[i].2.powi(2)).powi(2);
                    let d = dist2((x0, y0), (x1, y1));
                    let a = (r0 - r1 + d) / 2.0;
                    if d * r0 < a.powi(2) {
                        continue;
                    }
                    let cx = ((x1 - x0) * a + (y1 - y0) * (d * r0 - a.powi(2)).sqrt()) / d + x0;
                    let cy = ((y1 - y0) * a - (x1 - x0) * (d * r0 - a.powi(2)).sqrt()) / d + y0;
                    ans = ans.min(test(cx, cy, k, &v));
                    let cx = ((x1 - x0) * a - (y1 - y0) * (d * r0 - a.powi(2)).sqrt()) / d + x0;
                    let cy = ((y1 - y0) * a + (x1 - x0) * (d * r0 - a.powi(2)).sqrt()) / d + y0;
                    ans = ans.min(test(cx, cy, k, &v));
                }
            }
        }
    }
    println!("{}", ans);
}

fn test(cx: f64, cy: f64, k: usize, v: &Vec<(f64, f64, f64)>) -> f64 {
    let mut ts = vec![];
    for &(x, y, c) in v {
        ts.push(c * dist2((cx, cy), (x, y)).sqrt());
    }
    ts.sort_by(|x, y| x.partial_cmp(y).unwrap());
    ts[k - 1]
}

fn dist2(p: (f64, f64), q: (f64, f64)) -> f64 {
    (p.0 - q.0).powi(2) + (p.1 - q.1).powi(2)
}

fn circumcenter(p: (f64, f64), q: (f64, f64), r: (f64, f64)) -> ((f64, f64), f64) {
    let d = ((q.0 - p.0) * (r.1 - p.1) - (q.1 - p.1) * (r.0 - p.0)) * 2.0;
    if d.abs() < 1e-9 {
        ((0.0, 0.0), -1.0)
    } else {
        let o = (0.0, 0.0);
        let cx = ((q.1 - r.1) * dist2(o, p) + (r.1 - p.1) * dist2(o, q) + (p.1 - q.1) * dist2(o, r)) / d;
        let cy = - ((q.0 - r.0) * dist2(o, p) + (r.0 - p.0) * dist2(o, q) + (p.0 - q.0) * dist2(o, r)) / d;
        ((cx, cy), dist2((cx, cy), p))
    }
}