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

#include <bits/stdc++.h>
using namespace std;
typedef complex<double> P;
typedef pair<P, double> C;
typedef pair<P, P> L;

const double eps = 1e-8;

bool eq(double a, double b) { return -eps < a - b && a - b < eps; }

double cross(P a, P b) { return imag(b * conj(a)); }

bool isCrossCC(C a, C b) {
  double ar = a.second, br = b.second;
  double dist = abs(a.first - b.first);
  if (dist > ar + br + eps)
    return false;
  if (dist > ar + br - eps)
    return true;
  if (dist > abs(ar - br) + eps)
    return true;
  if (dist > abs(ar - br) - eps)
    return true;
  return false;
}

double Sqrt(double x) {
  if (x < 0)
    return 0;
  return sqrt(x);
}

P reflect(P a, P b, P c) {
  b -= a;
  c -= a;
  return a + conj(c / b) * b;
}

P getCrossCC(C a, C b) {
  P p1 = a.first, p2 = b.first;
  double r1 = a.second, r2 = b.second;
  double cA = (r1 * r1 + norm(p1 - p2) - r2 * r2) / (2.0 * r1 * abs(p1 - p2));
  return p1 + (p2 - p1) / abs(p1 - p2) * r1 * P(cA, Sqrt(1.0 - cA * cA));
}

int n;
int t[15];
int u[6];
bool used[15];
double ans = -1;

double calcArea(double a, double b, double c) {
  P p1 = P(0, 0);
  P p2 = P(b, 0);
  P p3 = getCrossCC(C(p1, a), C(p2, c));
  return abs(cross(p1 - p3, p2 - p3) * 0.5);
}

P getCrossLL(L line0, L line1) {
  P a = line0.first, b = line0.second;
  P c = line1.first, d = line1.second;
  a -= d;
  b -= d;
  c -= d;
  return d + a + (b - a) * imag(a / c) / imag(a / c - b / c);
}

bool check(int a, int b, int c) {
  if (a < b)
    swap(a, b);
  if (b < c)
    swap(b, c);
  if (a < b)
    swap(a, b);
  return (a < b + c);
}

void check() {

  double S = calcArea(u[0], u[1], u[2]);

  double h = 1e9;

  C ca = C(P(0, 0), u[4]);
  C cb = C(P(u[1], 0), u[5]);
  C cc = C(getCrossCC(C(ca.first, u[0]), C(cb.first, u[2])), u[3]);

  if (isCrossCC(ca, cb) == false)
    return;
  if (isCrossCC(cc, cb) == false)
    return;
  if (isCrossCC(ca, cc) == false)
    return;

  L fi = L(getCrossCC(ca, cb), getCrossCC(cb, ca));
  if (abs(fi.second - fi.first) < eps)
    return;

  L se = L(getCrossCC(cc, ca), getCrossCC(ca, cc));
  if (abs(se.second - se.first) < eps)
    return;

  L th = L(getCrossCC(cc, cb), getCrossCC(cb, cc));

  P target = getCrossLL(fi, se);

  P target2 = getCrossLL(th, se);
  if (abs(target - target2) > eps)
    return;

  double di;

  di = abs(P(0, 0) - target);
  double Ah = min(h, Sqrt(u[4] * u[4] - di * di));

  di = abs(P(u[1], 0) - target);
  double Bh = min(h, Sqrt(u[5] * u[5] - di * di));

  di = abs(cc.first - target);
  double Ch = min(h, Sqrt(cc.second * cc.second - di * di));
  if (!eq(Ah, Ch))
    return;
  if (!eq(Ah, Bh))
    return;
  if (!eq(Bh, Ch))
    return;
  h = min(Ah, Bh);
  h = min(h, Ah);

  ans = max(ans, h * S / 3.0);
}

void dfs(int cnt) {
  if (cnt >= 3 && !check(u[0], u[1], u[2]))
    return;
  if (cnt >= 5 && !check(u[0], u[3], u[4]))
    return;
  if (cnt >= 6 && !check(u[1], u[4], u[5]))
    return;
  if (cnt >= 6 && !check(u[2], u[3], u[5]))
    return;

  if (cnt == 6) {
    check();
  } else {
    for (int i = 0; i < n; i++) {
      if (used[i])
        continue;
      used[i] = true;
      u[cnt] = t[i];
      dfs(cnt + 1);
      used[i] = false;
    }
  }
}

int main() {
  while (1) {
    scanf("%d", &n);
    if (n == 0)
      break;

    for (int i = 0; i < n; i++) {
      scanf("%d", &t[i]);
    }

    sort(t, t + n);

    memset(used, false, sizeof(used));
    ans = -1;
    dfs(0);
    printf("%.10f\\n", ans);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef complex<double> P;
typedef pair<P, double> C;
typedef pair<P, P> L;

const double eps = 1e-8;

bool eq(double a, double b) { return -eps < a - b && a - b < eps; }

double cross(P a, P b) { return imag(b * conj(a)); }

bool isCrossCC(C a, C b) {
  double ar = a.second, br = b.second;
  double dist = abs(a.first - b.first);
  if (dist > ar + br + eps)
    return false;
  if (dist > ar + br - eps)
    return true;
  if (dist > abs(ar - br) + eps)
    return true;
  if (dist > abs(ar - br) - eps)
    return true;
  return false;
}

double Sqrt(double x) {
  if (x < 0)
    return 0;
  return sqrt(x);
}

P reflect(P a, P b, P c) {
  b -= a;
  c -= a;
  return a + conj(c / b) * b;
}

P getCrossCC(C a, C b) {
  P p1 = a.first, p2 = b.first;
  double r1 = a.second, r2 = b.second;
  double cA = (r1 * r1 + norm(p1 - p2) - r2 * r2) / (2.0 * r1 * abs(p1 - p2));
  return p1 + (p2 - p1) / abs(p1 - p2) * r1 * P(cA, Sqrt(1.0 - cA * cA));
}

int n;
int t[15];
int u[6];
bool used[15];
double ans = -1;

double calcArea(double a, double b, double c) {
  P p1 = P(0, 0);
  P p2 = P(b, 0);
  P p3 = getCrossCC(C(p1, a), C(p2, c));
  return abs(cross(p1 - p3, p2 - p3) * 0.5);
}

P getCrossLL(L line0, L line1) {
  P a = line0.first, b = line0.second;
  P c = line1.first, d = line1.second;
  a -= d;
  b -= d;
  c -= d;
  return d + a + (b - a) * imag(a / c) / imag(a / c - b / c);
}

bool check(int a, int b, int c) {
  if (a < b)
    swap(a, b);
  if (b < c)
    swap(b, c);
  if (a < b)
    swap(a, b);
  return (a < b + c);
}

void check() {
  if (!check(u[0], u[1], u[2]))
    return;
  if (!check(u[0], u[3], u[4]))
    return;
  if (!check(u[1], u[4], u[5]))
    return;
  if (!check(u[2], u[3], u[5]))
    return;

  double S = calcArea(u[0], u[1], u[2]);

  double h = 1e9;

  C ca = C(P(0, 0), u[4]);
  C cb = C(P(u[1], 0), u[5]);
  C cc = C(getCrossCC(C(ca.first, u[0]), C(cb.first, u[2])), u[3]);

  if (isCrossCC(ca, cb) == false)
    return;
  if (isCrossCC(cc, cb) == false)
    return;
  if (isCrossCC(ca, cc) == false)
    return;

  L fi = L(getCrossCC(ca, cb), getCrossCC(cb, ca));
  if (abs(fi.second - fi.first) < eps)
    return;

  L se = L(getCrossCC(cc, ca), getCrossCC(ca, cc));
  if (abs(se.second - se.first) < eps)
    return;

  L th = L(getCrossCC(cc, cb), getCrossCC(cb, cc));

  P target = getCrossLL(fi, se);

  P target2 = getCrossLL(th, se);
  if (abs(target - target2) > eps)
    return;

  double di;

  di = abs(P(0, 0) - target);
  double Ah = min(h, Sqrt(u[4] * u[4] - di * di));

  di = abs(P(u[1], 0) - target);
  double Bh = min(h, Sqrt(u[5] * u[5] - di * di));

  di = abs(cc.first - target);
  double Ch = min(h, Sqrt(cc.second * cc.second - di * di));
  if (!eq(Ah, Ch))
    return;
  if (!eq(Ah, Bh))
    return;
  if (!eq(Bh, Ch))
    return;
  h = min(Ah, Bh);
  h = min(h, Ah);

  ans = max(ans, h * S / 3.0);
}

void dfs(int cnt) {
  if (cnt == 6) {
    check();
  } else {
    for (int i = 0; i < n; i++) {
      if (used[i])
        continue;
      used[i] = true;
      u[cnt] = t[i];
      dfs(cnt + 1);
      used[i] = false;
    }
  }
}

int main() {
  while (1) {
    scanf("%d", &n);
    if (n == 0)
      break;

    for (int i = 0; i < n; i++) {
      scanf("%d", &t[i]);
    }
    memset(used, false, sizeof(used));
    ans = -1;
    dfs(0);
    printf("%.10f\\n", ans);
  }
  return 0;
}