提出 #10417928


ソースコード 拡げる

#include <bits/stdc++.h>
using namespace std;

using Real = long double;
using Point = complex< Real >;
const Real EPS = 1e-8, PI = acos(-1);

Point operator*(const Point &p, const Real &d) {
  return Point(real(p) * d, imag(p) * d);
}

inline bool eq(Real a, Real b) { return fabs(b - a) < EPS; }

istream &operator>>(istream &is, Point &p) {
  Real a, b;
  is >> a >> b;
  p = Point(a, b);
  return is;
}


struct Line {
  Point a, b;

  Line() = default;

  Line(Point a, Point b) : a(a), b(b) {}

  Line(Real A, Real B, Real C)
  {
    if(eq(A, 0)) a = Point(0, C / B), b = Point(1, C / B);
    else if(eq(B, 0)) b = Point(C / A, 0), b = Point(C / A, 1);
    else a = Point(0, C / B), b = Point(C / A, 0);
  }
};

Line g(Point a, Point b) {
    Point c = (a + b) / Point(2, 0);
    Point d = c + (b - a) * Point(0, 1);
    return Line(c, d);
}


struct Circle {
  Point p;
  Real r;

  Circle() = default;

  Circle(Point p, Real r) : p(p), r(r) {}
};

Circle h(Point a, Real acin, Point b, Real bcin) {
    assert(acin < bcin);
    Point ac = Point(acin, 0);
    Point bc = Point(bcin, 0);
    Point c = (a * ac + b * bc) / (ac + bc);
    Point d = (-a * ac + b * bc) / (-ac + bc);
    Real r = abs(c - d) / 2;
    return Circle((c + d) / Point(2, 0), r);
}

using Points = vector< Point >;
using Lines = vector< Line >;
using Circles = vector< Circle >;

Real cross(const Point &a, const Point &b) {
  return real(a) * imag(b) - imag(a) * real(b);
}

Real dot(const Point &a, const Point &b) {
  return real(a) * real(b) + imag(a) * imag(b);
}

Point projection(const Line &l, const Point &p) {
  double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
  return l.a + (l.a - l.b) * t;
}

Real distance(const Line &l, const Point &p) {
  return abs(p - projection(l, p));
}

bool intersect(const Line &l, const Line &m) {
  return abs(cross(l.b - l.a, m.b - m.a)) > EPS || abs(cross(l.b - l.a, m.b - l.a)) < EPS;
}

bool intersect(const Circle &c, const Line &l) {
  return distance(l, c.p) <= c.r + EPS;
}

int checker(Circle c1, Circle c2) {
  if(c1.r < c2.r) swap(c1, c2);
  Real d = abs(c1.p - c2.p);
  if(c1.r + c2.r < d) return 4;
  if(eq(c1.r + c2.r, d)) return 3;
  if(c1.r - c2.r < d) return 2;
  if(eq(c1.r - c2.r, d)) return 1;
  return 0;
}

bool intersect(Circle c1, Circle c2) {
    int tmp = checker(c1, c2);
    return 1 <= tmp and tmp <= 3;
}

Point crosspoint(const Line &l, const Line &m) {
  Real A = cross(l.b - l.a, m.b - m.a);
  Real B = cross(l.b - l.a, l.b - m.a);
  if(eq(abs(A), 0.0) && eq(abs(B), 0.0)) return m.a;
  return m.a + (m.b - m.a) * B / A;
}


pair< Point, Point > crosspoint(const Circle &c, const Line l) {
  Point pr = projection(l, c.p);
  Point e = (l.b - l.a) / abs(l.b - l.a);
  if(eq(distance(l, c.p), c.r)) return {pr, pr};
  double base = sqrt(c.r * c.r - norm(pr - c.p));
  return {pr - e * base, pr + e * base};
}

pair< Point, Point > crosspoint(const Circle &c1, const Circle &c2) {
  Real d = abs(c1.p - c2.p);
  Real a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
  Real t = atan2(c2.p.imag() - c1.p.imag(), c2.p.real() - c1.p.real());
  Point p1 = c1.p + Point(cos(t + a) * c1.r, sin(t + a) * c1.r);
  Point p2 = c1.p + Point(cos(t - a) * c1.r, sin(t - a) * c1.r);
  return {p1, p2};
}

int N, K;
Points P;
vector<int> c;
vector<long double> r;
Circles C;
Points p;
void input() {
    cin >> N >> K;
    P.resize(N);
    c.resize(N);
    C.resize(N);
    r.resize(N);
    for(int i = 0; i < N; i++) {
        cin >> P[i] >> c[i];
    }
}


void f(vector<int> v) {
    sort(v.begin(), v.end(), [](auto const &l, auto const &r) {
        return c[l] < c[r];
    });
    if(c[v[0]] == c[v[2]]) {
        auto l1 = g(P[v[0]], P[v[1]]);
        auto l2 = g(P[v[1]], P[v[2]]);
        if(intersect(l1, l2)) {
            p.push_back(crosspoint(l1, l2));
        }
    } else if(c[v[0]] == c[v[1]]) {
        auto l1 = g(P[v[0]], P[v[1]]);
        auto c1 = h(P[v[1]], c[v[1]], P[v[2]], c[v[2]]);
        if(intersect(c1, l1)) {
            auto tmp = crosspoint(c1, l1);
            p.push_back(tmp.first);
            p.push_back(tmp.second);
        }
    } else if(c[v[1]] == c[v[2]]) {
        auto l1 = g(P[v[1]], P[v[2]]);
        auto c1 = h(P[v[0]], c[v[0]], P[v[1]], c[v[1]]);
        if(intersect(c1, l1)) {
            auto tmp = crosspoint(c1, l1);
            p.push_back(tmp.first);
            p.push_back(tmp.second);
        }
    } else {
        auto c1 = h(P[v[0]], c[v[0]], P[v[1]], c[v[1]]);
        auto c2 = h(P[v[1]], c[v[1]], P[v[2]], c[v[2]]);
        if(intersect(c1, c2)) {
            auto tmp = crosspoint(c1, c2);
            p.push_back(tmp.first);
            p.push_back(tmp.second);
        }
    }
}

void solve() {
    p.clear();
    long double ans = 1e9;
    for(int i = 0; i < N; i++) {
        p.push_back(P[i]);
        for(int j = 0; j < i; j++) {
            p.push_back((P[i]*c[i]+P[j]*c[j]) / Point(c[i]+c[j],0));
            for(int k = 0; k < j; k++) {
                f({i, j, k});
            }
        }
    }
    for(auto tmp : p) {
        vector<long double> v;
        for(int i = 0; i < N; i++) {
            v.push_back(abs(tmp - P[i]) * c[i]);
        }
        sort(v.begin(), v.end());
        ans = min(ans, v[K-1]);
    }
    cout << fixed << setprecision(20) << ans << endl;
}

int main() {
    input();
    solve();
    return 0;
}

提出情報

提出日時
問題 F - Yakiniku Optimization Problem
ユーザ kort0n
言語 C++14 (GCC 5.4.1)
得点 600
コード長 5579 Byte
結果 AC
実行時間 186 ms
メモリ 1404 KiB

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 600 / 600
結果
AC × 2
AC × 67
セット名 テストケース
Sample 00-sample-00, 00-sample-01
All 00-sample-00, 00-sample-01, 01-handmade-00, 01-handmade-01, 01-handmade-02, 01-handmade-03, 01-handmade-04, 01-handmade-05, 01-handmade-06, 01-handmade-07, 01-handmade-08, 01-handmade-09, 01-handmade-10, 01-handmade-11, 02-random-00, 02-random-01, 02-random-02, 02-random-03, 02-random-04, 02-random-05, 02-random-06, 02-random-07, 02-random-08, 02-random-09, 02-random-10, 02-random-11, 02-random-12, 02-random-13, 02-random-14, 02-random-15, 02-random-16, 02-random-17, 02-random-18, 02-random-19, 02-random-20, 02-random-21, 02-random-22, 02-random-23, 02-random-24, 02-random-25, 02-random-26, 02-random-27, 02-random-28, 02-random-29, 02-random-30, 02-random-31, 02-random-32, 02-random-33, 02-random-34, 02-random-35, 02-random-36, 02-random-37, 02-random-38, 02-random-39, 02-random-40, 02-random-41, 02-random-42, 02-random-43, 02-random-44, 02-random-45, 02-random-46, 02-random-47, 02-random-48, 02-random-49, 03-killer-00, 03-killer-01, 03-killer-02
ケース名 結果 実行時間 メモリ
00-sample-00 AC 1 ms 256 KiB
00-sample-01 AC 1 ms 256 KiB
01-handmade-00 AC 1 ms 256 KiB
01-handmade-01 AC 1 ms 256 KiB
01-handmade-02 AC 156 ms 1404 KiB
01-handmade-03 AC 152 ms 1404 KiB
01-handmade-04 AC 152 ms 1404 KiB
01-handmade-05 AC 152 ms 1404 KiB
01-handmade-06 AC 130 ms 1404 KiB
01-handmade-07 AC 136 ms 1404 KiB
01-handmade-08 AC 151 ms 1404 KiB
01-handmade-09 AC 176 ms 1404 KiB
01-handmade-10 AC 1 ms 256 KiB
01-handmade-11 AC 2 ms 256 KiB
02-random-00 AC 146 ms 1404 KiB
02-random-01 AC 140 ms 1404 KiB
02-random-02 AC 145 ms 1404 KiB
02-random-03 AC 156 ms 1404 KiB
02-random-04 AC 166 ms 1404 KiB
02-random-05 AC 115 ms 1404 KiB
02-random-06 AC 107 ms 1404 KiB
02-random-07 AC 109 ms 896 KiB
02-random-08 AC 102 ms 896 KiB
02-random-09 AC 140 ms 1404 KiB
02-random-10 AC 124 ms 1404 KiB
02-random-11 AC 132 ms 1404 KiB
02-random-12 AC 156 ms 1404 KiB
02-random-13 AC 75 ms 896 KiB
02-random-14 AC 127 ms 1404 KiB
02-random-15 AC 87 ms 896 KiB
02-random-16 AC 127 ms 1404 KiB
02-random-17 AC 62 ms 896 KiB
02-random-18 AC 101 ms 896 KiB
02-random-19 AC 124 ms 1404 KiB
02-random-20 AC 98 ms 896 KiB
02-random-21 AC 107 ms 896 KiB
02-random-22 AC 94 ms 896 KiB
02-random-23 AC 141 ms 1404 KiB
02-random-24 AC 144 ms 1404 KiB
02-random-25 AC 125 ms 1404 KiB
02-random-26 AC 139 ms 1404 KiB
02-random-27 AC 87 ms 896 KiB
02-random-28 AC 82 ms 896 KiB
02-random-29 AC 86 ms 896 KiB
02-random-30 AC 103 ms 896 KiB
02-random-31 AC 151 ms 1404 KiB
02-random-32 AC 171 ms 1404 KiB
02-random-33 AC 135 ms 1404 KiB
02-random-34 AC 126 ms 1404 KiB
02-random-35 AC 105 ms 896 KiB
02-random-36 AC 127 ms 1404 KiB
02-random-37 AC 103 ms 896 KiB
02-random-38 AC 117 ms 1404 KiB
02-random-39 AC 157 ms 1404 KiB
02-random-40 AC 173 ms 1404 KiB
02-random-41 AC 70 ms 896 KiB
02-random-42 AC 116 ms 1404 KiB
02-random-43 AC 155 ms 1404 KiB
02-random-44 AC 144 ms 1404 KiB
02-random-45 AC 147 ms 1404 KiB
02-random-46 AC 97 ms 896 KiB
02-random-47 AC 186 ms 1404 KiB
02-random-48 AC 146 ms 1404 KiB
02-random-49 AC 178 ms 1404 KiB
03-killer-00 AC 156 ms 1404 KiB
03-killer-01 AC 164 ms 1404 KiB
03-killer-02 AC 103 ms 896 KiB