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 xyc = (0..n).map(|_| (sc.read(), sc.read(), sc.read())).collect();

    let mut ng = 0.0;
    let mut ok = 1e10;
    loop {
        let t = (ng + ok) / 2.0;
        if is_ok(&xyc, k, t) {
            if ok == t {
                break;
            }
            ok = t;
        } else {
            if ng == t {
                break;
            }
            ng = t;
        }
    }

    println!("{}", ok);
}

fn is_ok(xyc: &Vec<(f64, f64, f64)>, k: usize, t: f64) -> bool {
    let circles: Vec<_> = xyc.iter().map(|&(x, y, c)| (Point(x, y), t / c)).collect();
    let n = circles.len();

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

    for p in candidates.into_iter() {
        let mut count = 0;
        for i in 0..n {
            let d = (p - circles[i].0).abs();
            if d <= circles[i].1 + 1e-6 {
                count += 1;
            }
        }

        if count >= k {
            return true;
        }
    }
    false
}

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

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)]
}

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) -> IO<R, W> {
        IO(r, std::io::BufWriter::new(w))
    }
    pub fn write<S: std::ops::Deref<Target = str>>(&mut self, s: S) {
        use std::io::Write;
        self.1.write(s.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()
    }
}