Problem p00880 (C++) — buggy submission, verdict: Time Limit Exceeded

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

const int LOOP = 80;
const double EPS = 1e-8;
const double eps = 1e-8;
const double INF = 1e12;
const double PI = acos(-1);
typedef complex<double> P;
namespace std {
bool operator<(const P &a, const P &b) {
  return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
}
} // namespace std
double cross(const P &a, const P &b) { return imag(conj(a) * b); }
double dot(const P &a, const P &b) { return real(conj(a) * b); }

struct L : public vector<P> {
  L() {}
  L(const P &a, const P &b) {
    push_back(a);
    push_back(b);
  }
};

typedef vector<P> G;

struct C {
  P p;
  double r;
  C() {}
  C(const P &p, double r) : p(p), r(r) {}
};

int ccw(P a, P b, P c) {
  b -= a;
  c -= a;
  if (cross(b, c) > 0)
    return +1; // counter clockwise
  if (cross(b, c) < 0)
    return -1; // clockwise
  if (dot(b, c) < 0)
    return +2; // c--a--b on line
  if (norm(b) < norm(c))
    return -2; // a--b--c on line
  return 0;
}

P crosspoint(const L &l, const L &m) {
  double A = cross(l[1] - l[0], m[1] - m[0]);
  double B = cross(l[1] - l[0], l[1] - m[0]);
  if (abs(A) < EPS && abs(B) < EPS)
    return m[0]; // same line
  if (abs(A) < EPS)
    assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m[0] + B / A * (m[1] - m[0]);
}

int intersectCC(const C &c1, const C &c2) {
  double d = std::abs(c1.p - c2.p), r1 = c1.r, r2 = c2.r;
  if (r1 + r2 < d)
    return 0; // ??¢????????????
  if (std::abs(r1 + r2 - d) < eps)
    return -2; // ?????\\
	if(std::abs(d + r1 - r2) < eps) return +1;  // c1 ??? c2 ????????§?????\\
	if(std::abs(d + r2 - r1) < eps) return -1;  // c2 ??? c1 ????????§?????\\
	if(d + r1 < r2) return +3;                  // c1 ??? c2 ??????
  if (d + r2 < r1)
    return -3; // c2 ??? c1 ??????
  return 2;    // 2?????????????????????
}

P projection(const L &l, const P &p) {
  double t = dot(p - l[0], l[0] - l[1]) / norm(l[0] - l[1]);
  return l[0] + t * (l[0] - l[1]);
}

double distanceLP(const L &l, const P &p) { return abs(p - projection(l, p)); }

std::vector<P> crosspointCL(const C &c, const L &l) {
  std::vector<P> res;
  double d = distanceLP(l, c.p); // ????????¨??´???????????¢
  if (d > c.r)
    return res; // ??¢????????????

  if (std::abs(d - c.r) < eps) { // ?§?????????????
    res.push_back(projection(l, c.p));
    return res;
  }
  P h = projection(l, c.p);
  P u = std::sqrt(c.r * c.r - d * d) * (l[1] - l[0]) / std::abs(l[1] - l[0]);
  res.push_back(h + u);
  res.push_back(h - u);
  return res;
}

P p[3];
L ls[3];
P no[3];

bool InTriangle(P p) {
  for (int i = 0; i < 3; i++) {
    if (ccw(ls[i][0], ls[i][1], p) != 1)
      return false;
  }
  return true;
}

bool InTriangle(C c) {
  for (int i = 0; i < 3; i++) {
    auto res = crosspointCL(c, ls[i]);
    if (res.size() == 2)
      return false;
  }
  return true;
}

void PrintC(C c) {
  cout << "Circle " << c.p.real() << " " << c.p.imag() << " " << c.r << endl;
}

double d(double x1, double y1, double x2, double y2) {
  x1 -= x2, y1 -= y2;
  return sqrt(x1 * x1 + y1 * y1);
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
#ifdef LOCAL
  std::ifstream in("in");
  std::cin.rdbuf(in.rdbuf());
#endif

  while (true) {
    double sum = 0;
    for (int i = 0; i < 3; i++) {
      double x, y;
      cin >> x >> y;
      sum += x + y;
      p[i] = P(x, y);
    }
    if (abs(sum) < 1e-6)
      break;
    for (int i = 0; i < 3; i++) {
      P p1 = p[i], p2 = p[(i + 1) % 3];
      ls[i] = L(p1, p2);
      double d = abs(p1 - p2);
      no[i] = (p2 - p1) / d * polar(1.0, PI / 2.0);
    }

    double lb1 = 1e-6, ub1 = 1e6;
    C c1, c2, c3;
    for (int loop1 = 0; loop1 < LOOP; loop1++) {
      double mid1 = (lb1 + ub1) / 2.0;
      P p1;
      {
        L l1 = ls[0], l2 = ls[1];
        l1[0] += no[0] * mid1;
        l1[1] += no[0] * mid1;
        l2[0] += no[1] * mid1;
        l2[1] += no[1] * mid1;
        p1 = crosspoint(l1, l2);
        if (!InTriangle(p1) || !InTriangle(C(p1, mid1))) {
          ub1 = mid1;
          continue;
        }
      }
      c1 = C(p1, mid1);

      double lb2 = 1e-6, ub2 = 1e6;
      P p2;

      for (int loop2 = 0; loop2 < LOOP; loop2++) {
        double mid2 = (lb2 + ub2) / 2.0;
        {
          L l1 = ls[1], l2 = ls[2];
          l1[0] += no[1] * mid2;
          l1[1] += no[1] * mid2;
          l2[0] += no[2] * mid2;
          l2[1] += no[2] * mid2;
          p2 = crosspoint(l1, l2);
          if (!InTriangle(p2) || !InTriangle(C(p2, mid2)) ||
              intersectCC(c1, C(p2, mid2)) != 0) {
            ub2 = mid2;
          } else {
            lb2 = mid2;
          }
        }
      }
      c2 = C(p2, lb2);

      double dist = abs(c1.p - c2.p);
      if (dist > c1.r + c2.r + eps) {
        lb1 = mid1;
        continue;
      }

      // PrintC(c1);
      // PrintC(c2);

      // c1??¨??\\?????????c3????±???????
      double lb3 = 1e-6, ub3 = 1e6;
      P p3;
      for (int loop2 = 0; loop2 < LOOP; loop2++) {
        double mid3 = (lb3 + ub3) / 2.0;
        {
          L l1 = ls[2], l2 = ls[0];
          l1[0] += no[2] * mid3;
          l1[1] += no[2] * mid3;
          l2[0] += no[0] * mid3;
          l2[1] += no[0] * mid3;
          p3 = crosspoint(l1, l2);
          if (!InTriangle(p3) || !InTriangle(C(p3, mid3)) ||
              intersectCC(c1, C(p3, mid3)) != 0) {
            ub3 = mid3;
          } else {
            lb3 = mid3;
          }
        }
      }
      c3 = C(p3, lb3);

      dist = abs(p2 - p3);
      if (dist > c2.r + c3.r)
        ub1 = mid1;
      else
        lb1 = mid1;
      // PrintC(c1);
      // PrintC(c2);
      // PrintC(c3);
    }

    cout << fixed << setprecision(15) << c3.r << " " << c1.r << " " << c2.r
         << endl;
    // PrintC(c1);
    // PrintC(c2);
    // PrintC(c3);
  }
}

Error: TLE

Fixed submission:

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

const double EPS = 1e-8;
const double eps = 1e-8;
const double INF = 1e12;
const double PI = acos(-1);
typedef complex<double> P;
namespace std {
bool operator<(const P &a, const P &b) {
  return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
}
} // namespace std
double cross(const P &a, const P &b) { return imag(conj(a) * b); }
double dot(const P &a, const P &b) { return real(conj(a) * b); }

struct L : public vector<P> {
  L() {}
  L(const P &a, const P &b) {
    push_back(a);
    push_back(b);
  }
};

typedef vector<P> G;

struct C {
  P p;
  double r;
  C() {}
  C(const P &p, double r) : p(p), r(r) {}
};

int ccw(P a, P b, P c) {
  b -= a;
  c -= a;
  if (cross(b, c) > 0)
    return +1; // counter clockwise
  if (cross(b, c) < 0)
    return -1; // clockwise
  if (dot(b, c) < 0)
    return +2; // c--a--b on line
  if (norm(b) < norm(c))
    return -2; // a--b--c on line
  return 0;
}

P crosspoint(const L &l, const L &m) {
  double A = cross(l[1] - l[0], m[1] - m[0]);
  double B = cross(l[1] - l[0], l[1] - m[0]);
  if (abs(A) < EPS && abs(B) < EPS)
    return m[0]; // same line
  if (abs(A) < EPS)
    assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m[0] + B / A * (m[1] - m[0]);
}

int intersectCC(const C &c1, const C &c2) {
  double d = std::abs(c1.p - c2.p), r1 = c1.r, r2 = c2.r;
  if (r1 + r2 < d)
    return 0; // ??¢????????????
  if (std::abs(r1 + r2 - d) < eps)
    return -2; // ?????\\
	if(std::abs(d + r1 - r2) < eps) return +1;  // c1 ??? c2 ????????§?????\\
	if(std::abs(d + r2 - r1) < eps) return -1;  // c2 ??? c1 ????????§?????\\
	if(d + r1 < r2) return +3;                  // c1 ??? c2 ??????
  if (d + r2 < r1)
    return -3; // c2 ??? c1 ??????
  return 2;    // 2?????????????????????
}

P projection(const L &l, const P &p) {
  double t = dot(p - l[0], l[0] - l[1]) / norm(l[0] - l[1]);
  return l[0] + t * (l[0] - l[1]);
}

double distanceLP(const L &l, const P &p) { return abs(p - projection(l, p)); }

std::vector<P> crosspointCL(const C &c, const L &l) {
  std::vector<P> res;
  double d = distanceLP(l, c.p); // ????????¨??´???????????¢
  if (d > c.r)
    return res; // ??¢????????????

  if (std::abs(d - c.r) < eps) { // ?§?????????????
    res.push_back(projection(l, c.p));
    return res;
  }
  P h = projection(l, c.p);
  P u = std::sqrt(c.r * c.r - d * d) * (l[1] - l[0]) / std::abs(l[1] - l[0]);
  res.push_back(h + u);
  res.push_back(h - u);
  return res;
}

P p[3];
L ls[3];
P no[3];

bool InTriangle(P p) {
  for (int i = 0; i < 3; i++) {
    if (ccw(ls[i][0], ls[i][1], p) != 1)
      return false;
  }
  return true;
}

bool InTriangle(C c) {
  for (int i = 0; i < 3; i++) {
    auto res = crosspointCL(c, ls[i]);
    if (res.size() == 2)
      return false;
  }
  return true;
}

void PrintC(C c) {
  cout << "Circle " << c.p.real() << " " << c.p.imag() << " " << c.r << endl;
}

double d(double x1, double y1, double x2, double y2) {
  x1 -= x2, y1 -= y2;
  return sqrt(x1 * x1 + y1 * y1);
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
#ifdef LOCAL
  std::ifstream in("in");
  std::cin.rdbuf(in.rdbuf());
#endif

  while (true) {
    double sum = 0;
    for (int i = 0; i < 3; i++) {
      double x, y;
      cin >> x >> y;
      sum += x + y;
      p[i] = P(x, y);
    }
    if (abs(sum) < 1e-6)
      break;
    for (int i = 0; i < 3; i++) {
      P p1 = p[i], p2 = p[(i + 1) % 3];
      ls[i] = L(p1, p2);
      double d = abs(p1 - p2);
      no[i] = (p2 - p1) / d * polar(1.0, PI / 2.0);
    }

    double lb1 = 1e-6, ub1 = 1e6;
    C c1, c2, c3;
    for (int loop1 = 0; loop1 < 100; loop1++) {
      double mid1 = (lb1 + ub1) / 2.0;
      P p1;
      {
        L l1 = ls[0], l2 = ls[1];
        l1[0] += no[0] * mid1;
        l1[1] += no[0] * mid1;
        l2[0] += no[1] * mid1;
        l2[1] += no[1] * mid1;
        p1 = crosspoint(l1, l2);
        if (!InTriangle(p1) || !InTriangle(C(p1, mid1))) {
          ub1 = mid1;
          continue;
        }
      }
      c1 = C(p1, mid1);

      double lb2 = 1e-6, ub2 = 1e6;
      P p2;

      for (int loop2 = 0; loop2 < 100; loop2++) {
        double mid2 = (lb2 + ub2) / 2.0;
        {
          L l1 = ls[1], l2 = ls[2];
          l1[0] += no[1] * mid2;
          l1[1] += no[1] * mid2;
          l2[0] += no[2] * mid2;
          l2[1] += no[2] * mid2;
          p2 = crosspoint(l1, l2);
          if (!InTriangle(p2) || !InTriangle(C(p2, mid2)) ||
              intersectCC(c1, C(p2, mid2)) != 0) {
            ub2 = mid2;
          } else {
            lb2 = mid2;
          }
        }
      }
      c2 = C(p2, lb2);

      double dist = abs(c1.p - c2.p);
      if (dist > c1.r + c2.r + eps) {
        lb1 = mid1;
        continue;
      }

      // PrintC(c1);
      // PrintC(c2);

      // c1??¨??\\?????????c3????±???????
      double lb3 = 1e-6, ub3 = 1e6;
      P p3;
      for (int loop2 = 0; loop2 < 100; loop2++) {
        double mid3 = (lb3 + ub3) / 2.0;
        {
          L l1 = ls[2], l2 = ls[0];
          l1[0] += no[2] * mid3;
          l1[1] += no[2] * mid3;
          l2[0] += no[0] * mid3;
          l2[1] += no[0] * mid3;
          p3 = crosspoint(l1, l2);
          if (!InTriangle(p3) || !InTriangle(C(p3, mid3)) ||
              intersectCC(c1, C(p3, mid3)) != 0) {
            ub3 = mid3;
          } else {
            lb3 = mid3;
          }
        }
      }
      c3 = C(p3, lb3);

      dist = abs(p2 - p3);
      if (dist > c2.r + c3.r)
        ub1 = mid1;
      else
        lb1 = mid1;
      // PrintC(c1);
      // PrintC(c2);
      // PrintC(c3);
    }

    cout << fixed << setprecision(15) << c3.r << " " << c1.r << " " << c2.r
         << endl;
    // PrintC(c1);
    // PrintC(c2);
    // PrintC(c3);
  }
}