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

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);

    int N = scanner.nextInt();
    int K = scanner.nextInt();
    Niku[] nikus = new Niku[N];
    for (int i = 0; i < N; i++) {
      nikus[i] = new Niku(scanner.nextInt(), scanner.nextInt(), scanner.nextInt());
    }

    double left = 0.d;
    double right = 400_000.d;
    while (right - left > 1e-9) {
      double mid = (right + left) / 2;
      List<Point> intersects = new ArrayList<>();
      for (int i = 1; i < N; i++) {
        for (int j = 0; j < i; j++) {
          intersects.addAll(intersects(nikus[i].loc, mid / nikus[i].c, nikus[j].loc, mid / nikus[j].c));
        }
      }
      if (suffice(N, K, nikus, mid, intersects)) {
        right = mid;
      } else {
        left = mid;
      }
    }
    System.out.println(right);
  }

  private static boolean suffice(int n, int k, Niku[] nikus, double mid, List<Point> intersects) {
    for (Point p : intersects) {
      int count = 0;
      for (int i = 0; i < n; i++) {
        if (nikus[i].loc.dist(p) < mid / nikus[i].c + 1e-9) count++;
      }
      if (count >= k) {
        return true;
      }
    }
    return false;
  }

  private static class Niku {
    private final Point loc;
    private final int c;

    private Niku(int x, int y, int c) {
      this.loc = new Point(x, y);
      this.c = c;
    }
  }

  private static List<Point> intersects(Point c1, double r1, Point c2, double r2) {
    List<Point> list = new ArrayList<>();
    double dist = c1.dist(c2);
    if (dist > r1 + r2 + 1e-9) return list;
    if (dist < Math.abs(r1 - r2) + 1e-9) {
      if (Double.compare(r1, r2) < 0) list.add(c1);
      else list.add(c2);
      return list;
    }
    double cm = (r1 * r1 - r2 * r2 + dist * dist) / dist / 2;
    Point m = c2.subtract(c1).scale(cm / dist).add(c1);
    double pm = Math.sqrt(r1 * r1 - cm * cm);
    Point mc = c1.subtract(m).scale(pm / cm);
    list.add(mc.rotate(Math.PI / 2).add(m));
    list.add(mc.rotate(-Math.PI / 2).add(m));
    return list;
  }

  public static class Point {
    public final double x;
    public final double y;

    public Point(double x, double y) {
      this.x = x;
      this.y = y;
    }

    public Point scale(double s) {
      return new Point(x * s, y * s);
    }

    public Point subtract(Point another) {
      return new Point(x - another.x, y - another.y);
    }

    public Point add(Point another) {
      return new Point(x + another.x, y + another.y);
    }

    public double dist() {
      return Math.sqrt(x * x + y * y);
    }

    public double distSq(Point another) {
      return (another.x - x) * (another.x - x) + (another.y - y) * (another.y - y);
    }

    public double dist(Point another) {
      return Math.sqrt(distSq(another));
    }

    public Point rotate(double theta) {
      double newX = x * Math.cos(theta) - y * Math.sin(theta);
      double newY = x * Math.sin(theta) + y * Math.cos(theta);
      return new Point(newX, newY);
    }

    @Override public String toString() {
      return "(" + x + ", " + y + ')';
    }
  }
}