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)

fn main() {
    let (r, w) = (std::io::stdin(), std::io::stdout());
    let mut sc = IO::new(r.lock(), w.lock());

    let n: usize = sc.read();
    let k: usize = sc.read();

    let mut circles = vec![];
    for _ in 0..n {
        let x: f64 = sc.read();
        let y: f64 = sc.read();
        let c: f64 = sc.read();
        circles.push((x, y, c));
    }

    let mut ok = 1e15;
    let mut ng = 0.0;
    let mut p_ok = ok;
    let mut p_ng = ng;
    loop {
        let time = (ok + ng) / 2.0;

        if is_ok(&circles, k, time) {
            ok = time;
        } else {
            ng = time;
        }

        if p_ok == ok && p_ng == ng {
            break;
        }
        p_ok = ok;
        p_ng = ng;
    }

    println!("{}", (ok + ng) / 2.0);
}

fn is_ok(circles: &[(f64, f64, f64)], k: usize, time: f64) -> bool {
    let circles = circles
        .iter()
        .map(|&(x, y, c)| {
            let r = time / c;
            (Point(x, y), r)
        })
        .collect::<Vec<_>>();

    let n = circles.len();
    let mut candidates = vec![];
    for i in 0..n {
        for j in 0..i {
            let c1 = circles[i];
            let c2 = circles[j];
            candidates.extend(cc_intersect(c1, c2));
        }
        candidates.push(circles[i].0);
    }

    for p in candidates.into_iter() {
        let mut count = 0;
        for &(center, r) in circles.iter() {
            let dist = (center - p).abs();
            if dist <= r + 1e-7 {
                count += 1;
            }
        }
        if count >= k {
            return true;
        }
    }
    false
}

pub fn cc_intersect((p1, r1): (Point, f64), (p2, r2): (Point, f64)) -> Vec<Point> {
    let dist = (p1 - p2).abs();
    if dist > r1 + r2 {
        return Vec::new();
    }

    let rc = (dist * dist + r1 * r1 - r2 * r2) / (2. * dist);
    let rs = (r1 * r1 - rc * rc).sqrt();
    let diff = (p2 - p1) / dist;
    vec![p1 + diff * Point(rc, rs), p1 + diff * Point(rc, -rs)]
}

#[derive(Copy, Clone)]
pub struct Point(f64, f64);

impl Point {
    fn abs(self) -> f64 {
        let x = self.0;
        let y = self.1;
        (x * x + y * y).sqrt()
    }
}

impl ::std::ops::Add<Point> for Point {
    type Output = Point;
    fn add(self, rhs: Point) -> Point {
        Point(self.0 + rhs.0, self.1 + rhs.1)
    }
}

impl ::std::ops::Sub<Point> for Point {
    type Output = Point;
    fn sub(self, rhs: Point) -> Point {
        Point(self.0 - rhs.0, self.1 - rhs.1)
    }
}

impl ::std::ops::Div<f64> for Point {
    type Output = Point;
    fn div(self, rhs: f64) -> Point {
        Point(self.0 / rhs, self.1 / rhs)
    }
}

impl ::std::ops::Mul<Point> for Point {
    type Output = Point;
    fn mul(self, rhs: Point) -> Point {
        let Point(x1, y1) = self;
        let Point(x2, y2) = rhs;
        Point(x1 * x2 - y1 * y2, x1 * y2 + y1 * x2)
    }
}
pub struct IO<R, W: std::io::Write>(R, std::io::BufWriter<W>);

impl<R: std::io::Read, W: std::io::Write> IO<R, W> {
    pub fn new(r: R, w: W) -> Self {
        IO(r, std::io::BufWriter::new(w))
    }
    pub fn write<S: ToString>(&mut self, s: S) {
        use std::io::Write;
        self.1.write(s.to_string().as_bytes()).unwrap();
    }
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .0
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n' || b == b'\r' || b == b'\t')
            .take_while(|&b| b != b' ' && b != b'\n' && b != b'\r' && b != b'\t')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}