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

#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
#define EPS 1e-6

struct node {
  int x, y, len;
  double r;
  inline void cal_radius(double height) {
    r = sqrt(len * len - height * height);
  }
  inline void read() { scanf("%d%d%d", &x, &y, &len); }
} nodes[20];

int n;

inline bool intersect(const node &a, const node &b) {
  return hypot(a.x - b.x, a.y - b.y) < a.r + b.r + EPS;
}
inline double dist(const node &a, const node &b) {
  return hypot(a.x - b.x, a.y - b.y);
}

inline bool check(double height) {
  for (int i = 0; i < n; i++)
    nodes[i].cal_radius(height);

  for (int i = 0; i < n; i++)
    for (int j = i + 1; j < n; j++)
      if (!intersect(nodes[i], nodes[j]))
        return false;

  double left[20], right[20];
  double maxx = 1000.0, mini = -1000.0, mid;

  for (int i = 0; i < n; i++)
    maxx = fmin(maxx, nodes[i].y + nodes[i].r);
  for (int i = 0; i < n; i++)
    mini = fmax(mini, nodes[i].y - nodes[i].r);

  while (maxx - mini > EPS) {
    mid = (maxx + mini) * 0.5;

    for (int i = 0; i < n; i++) {
      double half_chord = sqrt(nodes[i].r * nodes[i].r -
                               (nodes[i].y - mid) * (nodes[i].y - mid));
      left[i] = nodes[i].x - half_chord;
      right[i] = nodes[i].x + half_chord;
    }

    bool up = false, down = false;
    for (int i = 0; i < n; i++)
      for (int j = i + 1; j < n; j++)
        if (fmax(left[i], left[j]) > fmin(right[i], right[j]) + EPS) {
          double nxty = nodes[i].y + (nodes[j].y - nodes[i].y) * nodes[i].r /
                                         dist(nodes[i], nodes[j]);
          if (nxty > mid)
            up = true;
          else
            down = true;
        }

    if (up && down)
      return false;
    if (!up && !down)
      return true;
    if (up)
      mini = mid;
    if (down)
      maxx = mid;
  }
  return false;
}

int main() {
  while (scanf("%d", &n) == 1 && n) {
    for (int i = 0; i < n; i++)
      nodes[i].read();

    double maxx = 1000.0, mini = 0.0, mid;
    for (int i = 0; i < n; i++)
      maxx = fmin(maxx, nodes[i].len);

    while (maxx - mini > EPS) {
      double mid = (maxx + mini) * 0.5;

      if (check(mid))
        mini = mid;
      else
        maxx = mid;
    }

    printf("%.7lf\\n", maxx);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
#define EPS 1e-8

struct node {
  int x, y, len;
  double r;
  inline void cal_radius(double height) {
    r = sqrt(len * len - height * height);
  }
  inline void read() { scanf("%d%d%d", &x, &y, &len); }
} nodes[20];

int n;

inline bool intersect(const node &a, const node &b) {
  return hypot(a.x - b.x, a.y - b.y) < a.r + b.r + EPS;
}
inline double dist(const node &a, const node &b) {
  return hypot(a.x - b.x, a.y - b.y);
}

inline bool check(double height) {
  for (int i = 0; i < n; i++)
    nodes[i].cal_radius(height);

  for (int i = 0; i < n; i++)
    for (int j = i + 1; j < n; j++)
      if (!intersect(nodes[i], nodes[j]))
        return false;

  double left[20], right[20];
  double maxx = 1000.0, mini = -1000.0, mid;

  for (int i = 0; i < n; i++)
    maxx = fmin(maxx, nodes[i].y + nodes[i].r);
  for (int i = 0; i < n; i++)
    mini = fmax(mini, nodes[i].y - nodes[i].r);

  while (mini < maxx) {
    mid = (maxx + mini) * 0.5;

    for (int i = 0; i < n; i++) {
      double half_chord = sqrt(nodes[i].r * nodes[i].r -
                               (nodes[i].y - mid) * (nodes[i].y - mid));
      left[i] = nodes[i].x - half_chord;
      right[i] = nodes[i].x + half_chord;
    }

    bool up = false, down = false;
    for (int i = 0; i < n; i++)
      for (int j = i + 1; j < n; j++)
        if (fmax(left[i], left[j]) > fmin(right[i], right[j]) + EPS) {
          double nxty = nodes[i].y + (nodes[j].y - nodes[i].y) * nodes[i].r /
                                         dist(nodes[i], nodes[j]);
          if (nxty > mid)
            up = true;
          else
            down = true;
        }

    if (up && down)
      return false;
    if (!up && !down)
      return true;
    if (up)
      mini = mid;
    if (down)
      maxx = mid;
  }
  return false;
}

int main() {
  while (scanf("%d", &n) == 1 && n) {
    for (int i = 0; i < n; i++)
      nodes[i].read();

    double maxx = 1000.0, mini = 0.0, mid;
    for (int i = 0; i < n; i++)
      maxx = fmin(maxx, nodes[i].len);

    while (maxx - mini > EPS) {
      double mid = (maxx + mini) * 0.5;

      if (check(mid))
        mini = mid;
      else
        maxx = mid;
    }

    printf("%.7lf\\n", maxx);
  }
  return 0;
}