Problem p00771 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <utility>
#include <vector>
using namespace std;
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T> inline string toString(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
const double EPS = 1e-9;
const double PI = acos(-1.0);

#include <complex>
typedef complex<double> P;
#define LT(x, y) ((x) - (y) <= -EPS)

vector<P> cross_circles(P c1, double r1, P c2, double r2) {
  double d = abs(c2 - c1);
  if (LT(r1 + r2, d) || LT(d, fabs(r1 - r2)))
    return vector<P>();
  double l = 0.5 * ((r1 * r1 - r2 * r2) / d + d);
  double h = sqrt(r1 * r1 - l * l);
  vector<P> ret(2);
  ret[0] = P(l, +h) * (c2 - c1) / d + c1;
  ret[1] = P(l, -h) * (c2 - c1) / d + c1;
  return ret;
}

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

bool ok(vi &y, vi &x, vi &l, double h) {
  int n = y.size();
  vector<P> all_cross;
  REP(i, n) {
    FOR(j, i + 1, n) {
      if (l[i] + EPS < h || l[j] + EPS < h) {
        return false;
      }
      double di = sqrt(l[i] * l[i] - h * h);
      double dj = sqrt(l[j] * l[j] - h * h);
      double dist2 = distance(y[i], x[i], y[j], x[j]);
      bool intersected = di + dj + EPS > dist2;
      vector<P> cross = cross_circles(P(y[i], x[i]), di, P(y[j], x[j]), dj);
      if (cross.size() == 0) {
        if (!intersected) {
          return false;
        }
      } else {
        all_cross.push_back(cross[0]);
        all_cross.push_back(cross[1]);
      }
    }
    all_cross.push_back(P(y[i], x[i]));
  }

  REP(ci, all_cross.size()) {
    bool ok = true;
    REP(k, n) {
      double dk = sqrt(l[k] * l[k] - h * h);
      if (distance(y[k], x[k], all_cross[ci].real(), all_cross[ci].imag()) >
          dk + EPS) {
        ok = false;
      }
    }
    if (ok) {
      return true;
    }
  }
  return false;
}

int main() {
  cout.precision(30);
  int n;
  while (cin >> n, n) {
    vi x(n), y(n), l(n);
    int maxl = 0;
    REP(i, n) {
      cin >> x[i] >> y[i] >> l[i];
      maxl = max(maxl, l[i]);
    }

    double lb = 1, ub = maxl;
    REP(time, 10000) {
      double mid = (lb + ub) / 2;
      if (!ok(y, x, l, mid)) {
        ub = mid;
      } else {
        lb = mid;
      }
    }
    cout << ub << endl;
  }
}

Fixed submission:
#include <algorithm>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <utility>
#include <vector>
using namespace std;
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T> inline string toString(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
const double EPS = 1e-9;
const double PI = acos(-1.0);

#include <complex>
typedef complex<double> P;
#define LT(x, y) ((x) - (y) <= -EPS)

vector<P> cross_circles(P c1, double r1, P c2, double r2) {
  double d = abs(c2 - c1);
  if (LT(r1 + r2, d) || LT(d, fabs(r1 - r2)))
    return vector<P>();
  double l = 0.5 * ((r1 * r1 - r2 * r2) / d + d);
  double h = sqrt(r1 * r1 - l * l);
  vector<P> ret(2);
  ret[0] = P(l, +h) * (c2 - c1) / d + c1;
  ret[1] = P(l, -h) * (c2 - c1) / d + c1;
  return ret;
}

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

bool ok(vi &y, vi &x, vi &l, double h) {
  int n = y.size();
  vector<P> all_cross;
  REP(i, n) {
    FOR(j, i + 1, n) {
      if (l[i] + EPS < h || l[j] + EPS < h) {
        return false;
      }
      double di = sqrt(l[i] * l[i] - h * h);
      double dj = sqrt(l[j] * l[j] - h * h);
      double dist2 = distance(y[i], x[i], y[j], x[j]);
      bool intersected = di + dj + EPS > dist2;
      vector<P> cross = cross_circles(P(y[i], x[i]), di, P(y[j], x[j]), dj);
      if (cross.size() == 0) {
        if (!intersected) {
          return false;
        }
      } else {
        all_cross.push_back(cross[0]);
        all_cross.push_back(cross[1]);
      }
    }
    all_cross.push_back(P(y[i], x[i]));
  }

  REP(ci, all_cross.size()) {
    bool ok = true;
    REP(k, n) {
      double dk = sqrt(l[k] * l[k] - h * h);
      if (distance(y[k], x[k], all_cross[ci].real(), all_cross[ci].imag()) >
          dk + EPS) {
        ok = false;
      }
    }
    if (ok) {
      return true;
    }
  }
  return false;
}

int main() {
  cout.precision(30);
  int n;
  while (cin >> n, n) {
    vi x(n), y(n), l(n);
    int maxl = 0;
    REP(i, n) {
      cin >> x[i] >> y[i] >> l[i];
      maxl = max(maxl, l[i]);
    }

    double lb = 1, ub = maxl;
    REP(time, 1000) {
      double mid = (lb + ub) / 2;
      if (!ok(y, x, l, mid)) {
        ub = mid;
      } else {
        lb = mid;
      }
    }
    cout << ub << endl;
  }
}