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 C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>

#define rep(i, n) for (ll i = 0; i < (n); i++)
#define rep2(i, a, b) for (ll i = (a); i < (b); i++)
#define chmax(x, v) do { x = max(x, v); } while (0)
#define chmin(x, v) do { x = min(x, v); } while (0)
typedef uint64_t ull;
typedef int64_t ll;
typedef std::pair<ll, ll> PLL;

using namespace std;

ll N, K;
vector<double> x,y,c;

const double EPS = 1e-9;
bool eq(double a, double b) {
  return abs(a-b) < EPS;
}
double pow2(double x) {
  return x * x;
}

class Vector2D {
 public:
  explicit Vector2D(double x = 0, double y = 0) : x(x), y(y) {}
  double x, y;
  double l1norm() const { return abs(x) + abs(y); }
  double l2norm() const { return sqrt(x * x + y * y); }
  double length() const { return l2norm(); }
  double distance(const Vector2D &r) const { return (*this - r).l2norm(); }

  Vector2D operator+(const Vector2D &r) const { return Vector2D(x + r.x, y + r.y); }
  Vector2D operator-(const Vector2D &r) const { return Vector2D(x - r.x, y - r.y); }
  Vector2D dot(const Vector2D &r) const { return Vector2D(x * r.x + x * r.y); } // 内積
  Vector2D cross(const Vector2D &r) const { return Vector2D(x * r.y - y * r.x); } // 外積
  Vector2D operator*(const double &t) const { return Vector2D(x*t, y*t); }
  Vector2D operator/(const double &t) const { return Vector2D(x/t, y/t); }
  string str() const { return "(" + to_string(x) + ", " + to_string(y) + ")"; }

  Vector2D &operator+=(const Vector2D &r) { x += r.x; y += r.y; return *this; }
  Vector2D &operator-=(const Vector2D &r) { x -= r.x; y -= r.y; return *this; }
  bool operator==(const Vector2D &r) const { return eq(x, r.x) && eq(y, r.y); }
  // 反時計回りに回転
  Vector2D rotate(const double &rad) const {
    return Vector2D(x * cos(rad) - y * sin(rad), x * sin(rad) + y * cos(rad));
  }
  Vector2D rotete90() const { return Vector2D(-y, x); }
};

class Circle {
 public:
   Vector2D o;
   double r;
   explicit Circle(double x = 0, double y = 0, double r = 0) : o(x,y), r(r) {}
   bool operator==(const Circle &c2) const {
     auto c1 = *this;
     return c1.o == c2.o && eq(c1.r, c2.r);
   }
   // 面積
   double area () const {
     return r * r * M_PI;
   }
   // 点がこの円に含まれているか
   bool contains(const Vector2D &p) {
     return o.distance(p) < r + EPS;
   }
   // 交点の座標を返す
   vector<Vector2D> intersections(const Circle &c2) const {
     // https://shogo82148.github.io/homepage/memo/geometry/circle-cross.html
     const auto &r1 = r, &r2 = c2.r;
     const auto x1 = (c2.o - o).x, y1 = (c2.o-o).y;
     const auto E = pow2(x1) + pow2(y1);
     const auto a = (E + pow2(r1) - pow2(r2)) / 2.0;
     const auto D = E * pow2(r1) - pow2(a);

     if (eq(D, 0)) return {o + Vector2D(a*x1 / E, a*y1 / E)};
     if (D < 0) return {};
     if (eq(E, 0)) return {};

     return {
       o + Vector2D((a*x1 + y1 * sqrt(D)) / E, (a*y1 - x1 * sqrt(D)) / E),
       o + Vector2D((a*x1 - y1 * sqrt(D)) / E, (a*y1 + x1 * sqrt(D)) / E)
     };

   }

   static void test() {
     {
       Circle c1(0,0,4), c2(2,0,2);
       auto actual = c1.intersections(c2);
       auto expected = vector<Vector2D>{Vector2D(4,0)};
       //cout << "actual.size=" << actual.size() << endl;
       //cout << "actual[0]=" << actual[0].str() << endl;
       // assert(actual == expected);
     }
     {
       Circle c1(0,0,4), c2(12,0,8);
       auto actual = c1.intersections(c2);
       auto expected = vector<Vector2D>{Vector2D(4,0)};
       assert(actual == expected);
     }
     {
       Circle c1(2,3,3), c2(1,-1,4);
       auto actual = c1.intersections(c2);
       assert(actual.size() == 2);
     }
   } 
};

bool f(double sec) {
  vector<Circle> v(N);
  rep(i, N) {
    v[i] = Circle(x[i], y[i], sec / c[i]);
  }

  vector<Vector2D> cand;
  rep(i, N) rep(j, N) {
    if (j >= i)
      continue;
    auto t = v[i].intersections(v[j]);
    cand.insert(cand.end(), t.begin(), t.end());
  }
  for (auto p : cand) {
    ll cnt = 0;
    rep(i, N) {
      if (v[i].contains(p))
        cnt++;
    }
    if (cnt >= K)
      return true;
  }
  return false;
}

signed main() {
  Circle::test();
  cin >> N >> K;
  x.resize(N);
  y.resize(N);
  c.resize(N);
  rep(i, N) {
    cin >> x[i] >> y[i] >> c[i];
  }

  double ng = 0, ok = 400000;
  rep(i, 1000) {
    double sec = (ok+ng)/2;
    if (f(sec)) {
      ok = sec;
      //printf("ok = %.f\n", ok);
    } else {
      ng = sec;
      //printf("ng = %.f\n", ng);
    }
  }

  printf("%.10f\n", ok);
  return 0;
}