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

#define __USE_MINGW_ANSI_STDIO 0
#include <bits/stdc++.h>

using namespace std;
using ll = long long;
#define int ll
using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
#define PB push_back

const ll LLINF = (1LL << 60);
const int INF = (1LL << 30);
const int MOD = 1000000007;

template <typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template <typename T> bool IN(T a, T b, T x) { return a <= x && x < b; }
template <typename T> T ceil(T a, T b) { return a / b + !!(a % b); }
template <class S, class T>
ostream &operator<<(ostream &out, const pair<S, T> &a) {
  out << '(' << a.first << ',' << a.second << ')';
  return out;
}
template <class T> ostream &operator<<(ostream &out, const vector<T> &a) {
  out << '[';
  REP(i, a.size()) {
    out << a[i];
    if (i != a.size() - 1)
      out << ',';
  }
  out << ']';
  return out;
}

int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};

const double EPS = 1e-8;

using R = double;
using P = complex<R>;
using L = pair<P, P>;
using G = vector<P>;
struct C {
  P c;
  R r;
  C() {}
  C(const P &a, const R &b) : c(a), r(b) {}
};
struct S : public L {
  S() {}
  S(const P &a, const P &b) : L(a, b) {}
};

inline int sgn(const R &r) { return (r > EPS) - (r < -EPS); }
inline R dot(const P &a, const P &b) {
  return real(a) * real(b) + imag(a) * imag(b);
}
inline R det(const P &a, const P &b) {
  return real(a) * imag(b) - imag(a) * real(b);
}
inline P vec(const L &l) { return l.second - l.first; }
namespace std {
bool operator<(const P &a, const P &b) {
  return sgn(real(a - b)) ? real(a - b) < 0 : sgn(imag(a - b)) < 0;
}
bool operator==(const P &a, const P &b) {
  return sgn(real(a - b)) == 0 && sgn(imag(a - b)) == 0;
}
bool cmp_y(const P &a, const P &b) {
  return sgn(imag(a - b)) ? imag(a - b) < 0 : sgn(real(a - b)) < 0;
}
} // namespace std

// P,L,Sについて入力
inline istream &operator>>(istream &is, P &p) {
  R x, y;
  is >> x >> y;
  p = P(x, y);
  return is;
}
inline istream &operator>>(istream &is, L &l) {
  P a, b;
  is >> a >> b;
  l = L(a, b);
  return is;
}
inline istream &operator>>(istream &is, S &s) {
  P a, b;
  is >> a >> b;
  s = S(a, b);
  return is;
}

// 射影
P inline projection(const L &l, const P &p) {
  R t = dot(p - l.first, l.first - l.second) / norm(l.first - l.second);
  return l.first + t * (l.first - l.second);
}
// 反射
P inline reflection(const L &l, const P &p) {
  return p + (R)2 * (projection(l, p) - p);
}

// 線分abから見たcの位置
enum CCW { LEFT = 1, RIGHT = 2, BACK = 4, FRONT = 8, ON_SEG = 16 };
int ccw(P a, P b, P c) {
  P p = (c - a) / (b - a);
  if (sgn(imag(p)) > 0)
    return LEFT;
  if (sgn(imag(p)) < 0)
    return RIGHT;
  if (sgn(real(p)) < 0)
    return BACK;
  if (sgn(real(p) - 1) > 0)
    return FRONT;
  return ON_SEG;
}

// 垂直,平行
inline bool vertical(L a, L b) { return sgn(dot(vec(a), vec(b))) == 0; }
inline bool parallel(L a, L b) { return sgn(det(vec(a), vec(b))) == 0; }
inline bool eal(L a, L b) { return vertical(a, b) && parallel(a, b); }

// 交差判定
template <bool strict = false> inline bool intersect(const L &l1, const L &l2) {
  if (strict)
    return sgn(det(vec(l1), vec(l2))) != 0;
  return sgn(det(vec(l1), vec(l2))) != 0 || l1 == l2;
}
template <bool strict = false> inline bool intersect(const L &l, const S &s) {
  if (strict)
    det(s.first, vec(l)) * det(s.second, vec(l)) < 0;
  return det(s.first, vec(l)) * det(s.second, vec(l)) <= 0;
}
template <bool strict = false> inline bool intersect(const S &s1, const S &s2) {
  int ccw1 =
      ccw(s1.first, s1.second, s2.first) | ccw(s1.first, s1.second, s2.second);
  int ccw2 =
      ccw(s2.first, s2.second, s1.first) | ccw(s2.first, s2.second, s1.second);
  if (strict)
    return (ccw1 & ccw2) == (LEFT | RIGHT);
  return (ccw1 & ccw2) == (LEFT | RIGHT) || ((ccw1 | ccw2) & ON_SEG);
}
template <bool strict = false> inline bool intersect(const S &s, const P &p) {
  return ccw(s.first, s.second, p) == ON_SEG;
}
template <bool strict = false> inline bool intersect(const L &l, const P &p) {
  return ccw(l.first, l.second, p) == ON_SEG ||
         ccw(l.first, l.second, p) == FRONT ||
         ccw(l.first, l.second, p) == BACK;
}
int intersect(const C &a, const C &b) {
  R dist = sqrt(norm(a.c - b.c)), r1 = a.r + b.r, r2 = abs(a.r - b.r);
  if (sgn(r1 - dist) < 0)
    return 4; // 円が離れている
  if (sgn(r1 - dist) == 0)
    return 3; // 外接
  if (sgn(r2 - dist) < 0 && sgn(dist - r1) < 0)
    return 2; // 交差
  if (sgn(dist - r2) == 0)
    return 1; // 内接
  return 0;   // 内部に含む
}

// 距離
R dist(const S &s, const P &p) {
  P q = projection(s, p);
  if (sgn(dot(s.second - s.first, p - s.first)) <= 0)
    q = s.first;
  if (sgn(dot(s.first - s.second, p - s.second)) <= 0)
    q = s.second;
  return abs(p - q);
}
R dist(const S &a, const S &b) {
  if (intersect(a, b))
    return 0;
  return min({dist(a, b.first), dist(a, b.second), dist(b, a.first),
              dist(b, a.second)});
}
R dist(const L &l, const P &p) {
  P q = projection(l, p);
  return abs(p - q);
}

// 交点 交差判定を先にすること!!!
inline P crosspoint(const L &l1, const L &l2) {
  R ratio = det(vec(l2), l2.first - l1.first) / det(vec(l2), vec(l1));
  return l1.first + vec(l1) * ratio;
}
// ToDo:そもそも交差しないとき
vector<P> crosspoint(C c, L l) {
  R d = dist(l, c.c), r = c.r;
  P m = projection(l, c.c);
  P x = sqrt(r * r - d * d) * vec(l) / abs(vec(l));
  vector<P> ret(2, m);
  ret[0] -= x;
  ret[1] += x;
  if (ret[1] < ret[0])
    swap(ret[0], ret[1]);
  return ret;
}
vector<P> crosspoint(C a, C b) {
  R d = abs(a.c - b.c);
  R t = (a.r * a.r - b.r * b.r + d * d) / 2 / d, h = sqrt(a.r * a.r - t * t);
  P m = t / abs(b.c - a.c) * (b.c - a.c) + a.c;
  auto n_vector = [&](P p) -> P { return P(-p.imag(), p.real()) / abs(p); };
  P n = n_vector(a.c - b.c);
  vector<P> ret(2, m);
  ret[0] -= h * n;
  ret[1] += h * n;
  if (ret[1] < ret[0])
    swap(ret[0], ret[1]);
  return ret;
}

// 面積 頂点が反時計回りに並んでいること
R area(const G &pol) {
  R ret = 0.0;
  REP(i, pol.size()) ret += det(pol[i], pol[(i + 1) % pol.size()]);
  return (ret / 2.0);
}

// 凸性の判定
bool isConvex(const G &pol) {
  REP(i, pol.size()) {
    if (sgn(det(pol[(i + 1) % pol.size()] - pol[i],
                pol[(i + 2) % pol.size()] - pol[i])) < 0) {
      return false;
    }
  }
  return true;
}

// 多角形と点の内包
// 2→in 1→on 0→out
int inPolygon(const G &pol, const P &p) {
  bool in = false;
  for (int i = 0; i < pol.size(); ++i) {
    P a = pol[i] - p, b = pol[(i + 1) % pol.size()] - p;
    if (imag(a) > imag(b))
      swap(a, b);
    if (imag(a) <= 0 && 0 < imag(b) && sgn(det(a, b)) < 0) {
      in = !in;
    }
    if (sgn(det(a, b)) == 0 && sgn(dot(a, b)) <= 0)
      return 1;
  }
  return in ? 2 : 0;
}

// 凸包 3点が一直線上に並ぶときに注意
// 凸包のうち一番左にある頂点の中で一番下の頂点から時計回り
G convex_hull(G ps) {
  int n = ps.size(), k = 0;
  sort(ps.begin(), ps.end());
  G r(2 * n);
  for (int i = 0; i < n; i++) {
    while (k > 1 && sgn(det(r[k - 1] - r[k - 2], ps[i] - r[k - 2])) < 0)
      k--;
    r[k++] = ps[i];
  }
  for (int i = n - 2, t = k; i >= 0; i--) {
    while (k > t && sgn(det(r[k - 1] - r[k - 2], ps[i] - r[k - 2])) < 0)
      k--;
    r[k++] = ps[i];
  }
  r.resize(k - 1);
  return r;
}

/*
3点が与えられたときに円を求める
返り値は{中心のx座標、y座標、半径}
3点が直線上に並んでいるときは{0, 0, -1}を返す
ToDo:見直す
*/
C calcCircle(R x1, R y1, R x2, R y2, R x3, R y3) {
  R ox, oy, a, b, c, d;
  R r1, r2, r3;

  a = x2 - x1;
  b = y2 - y1;
  c = x3 - x1;
  d = y3 - y1;
  R cx, cy, r;
  if ((a && d) || (b && c)) {
    ox = x1 + (d * (a * a + b * b) - b * (c * c + d * d)) / (a * d - b * c) / 2;
    if (b)
      oy = (a * (x1 + x2 - ox - ox) + b * (y1 + y2)) / b / 2;
    else
      oy = (c * (x1 + x3 - ox - ox) + d * (y1 + y3)) / d / 2;
    r1 = sqrt((ox - x1) * (ox - x1) + (oy - y1) * (oy - y1));
    r2 = sqrt((ox - x2) * (ox - x2) + (oy - y2) * (oy - y2));
    r3 = sqrt((ox - x3) * (ox - x3) + (oy - y3) * (oy - y3));
    cx = ox;
    cy = oy;
    r = (r1 + r2 + r3) / 3;
    return {P{cx, cy}, r};
  }

  return {P{0, 0}, -1};
}

// 2点p1, p2を通り、半径がrの円を2つ返す
vector<C> calcCircle(P p1, P p2, R r) {
  // 存在しない
  if (abs(p1 - p2) > 2 * r)
    return {};
  P p3 = {(p1.real() + p2.real()) / 2, (p1.imag() + p2.imag()) / 2};
  R l = abs(p1 - p3);
  P p1p2 = p2 - p1;
  R a = p1p2.real(), b = p1p2.imag();
  R dx1 = b * sqrt((r * r - l * l) / (a * a + b * b)),
    dy1 = a * sqrt((r * r - l * l) / (a * a + b * b));
  return {{{p3.real() + dx1, p3.imag() - dy1}, r},
          {{p3.real() - dx1, p3.imag() + dy1}, r}};
}

P p1[55], p2[55];
R d[55], h[55];
signed main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);

  while (true) {
    int n;
    cin >> n;
    if (!n)
      break;
    S s;
    cin >> s;
    REP(i, n) cin >> p1[i] >> p2[i] >> h[i];

    REP(i, n) {
      d[i] = INF;
      S tmp = S(p1[i], P{p1[i].real(), p2[i].imag()});
      chmin(d[i], dist(s, tmp));
      tmp = S(P{p1[i].real(), p2[i].imag()}, p2[i]);
      chmin(d[i], dist(s, tmp));
      tmp = S(p2[i], P{p2[i].real(), p1[i].imag()});
      chmin(d[i], dist(s, tmp));
      tmp = S(P{p2[i].real(), p1[i].imag()}, p1[i]);
      chmin(d[i], dist(s, tmp));
      if (p1[i].real() <= s.first.real() && s.first.real() <= p2[i].real() &&
          p1[i].imag() <= s.first.imag() && s.first.imag() <= p2[i].imag()) {
        d[i] = 0;
      }
      if (p1[i].real() <= s.second.real() && s.second.real() <= p2[i].real() &&
          p1[i].imag() <= s.second.imag() && s.second.imag() <= p2[i].imag()) {
        d[i] = 0;
      }
    }

    auto check = [&](R r) -> bool {
      REP(i, n) {
        if (r < h[i]) {
          if (r > d[i])
            return false;
        } else {
          R tmp = r * r - (r - h[i]) * (r - h[i]);
          if (tmp > d[i] * d[i])
            return false;
        }
      }
      return true;
    };

    bool flag = false;
    const R dr = 0.001 / 2;
    for (R r = 1000; r >= 0; r -= dr) {
      if (check(r)) {
        cout << fixed << setprecision(9) << r << endl;
        flag = true;
        break;
      }
    }

    if (!flag)
      cout << 0 << endl;
  }

  return 0;
}


Error: TLE

Fixed submission:

#define __USE_MINGW_ANSI_STDIO 0
#include <bits/stdc++.h>

using namespace std;
using ll = long long;
#define int ll
using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
#define PB push_back

const ll LLINF = (1LL << 60);
const int INF = (1LL << 30);
const int MOD = 1000000007;

template <typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template <typename T> bool IN(T a, T b, T x) { return a <= x && x < b; }
template <typename T> T ceil(T a, T b) { return a / b + !!(a % b); }
template <class S, class T>
ostream &operator<<(ostream &out, const pair<S, T> &a) {
  out << '(' << a.first << ',' << a.second << ')';
  return out;
}
template <class T> ostream &operator<<(ostream &out, const vector<T> &a) {
  out << '[';
  REP(i, a.size()) {
    out << a[i];
    if (i != a.size() - 1)
      out << ',';
  }
  out << ']';
  return out;
}

int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};

const double EPS = 1e-8;

using R = long double;
using P = complex<R>;
using L = pair<P, P>;
using G = vector<P>;
struct C {
  P c;
  R r;
  C() {}
  C(const P &a, const R &b) : c(a), r(b) {}
};
struct S : public L {
  S() {}
  S(const P &a, const P &b) : L(a, b) {}
};

inline int sgn(const R &r) { return (r > EPS) - (r < -EPS); }
inline R dot(const P &a, const P &b) {
  return real(a) * real(b) + imag(a) * imag(b);
}
inline R det(const P &a, const P &b) {
  return real(a) * imag(b) - imag(a) * real(b);
}
inline P vec(const L &l) { return l.second - l.first; }
namespace std {
bool operator<(const P &a, const P &b) {
  return sgn(real(a - b)) ? real(a - b) < 0 : sgn(imag(a - b)) < 0;
}
bool operator==(const P &a, const P &b) {
  return sgn(real(a - b)) == 0 && sgn(imag(a - b)) == 0;
}
bool cmp_y(const P &a, const P &b) {
  return sgn(imag(a - b)) ? imag(a - b) < 0 : sgn(real(a - b)) < 0;
}
} // namespace std

// P,L,Sについて入力
inline istream &operator>>(istream &is, P &p) {
  R x, y;
  is >> x >> y;
  p = P(x, y);
  return is;
}
inline istream &operator>>(istream &is, L &l) {
  P a, b;
  is >> a >> b;
  l = L(a, b);
  return is;
}
inline istream &operator>>(istream &is, S &s) {
  P a, b;
  is >> a >> b;
  s = S(a, b);
  return is;
}

// 射影
P inline projection(const L &l, const P &p) {
  R t = dot(p - l.first, l.first - l.second) / norm(l.first - l.second);
  return l.first + t * (l.first - l.second);
}
// 反射
P inline reflection(const L &l, const P &p) {
  return p + (R)2 * (projection(l, p) - p);
}

// 線分abから見たcの位置
enum CCW { LEFT = 1, RIGHT = 2, BACK = 4, FRONT = 8, ON_SEG = 16 };
int ccw(P a, P b, P c) {
  P p = (c - a) / (b - a);
  if (sgn(imag(p)) > 0)
    return LEFT;
  if (sgn(imag(p)) < 0)
    return RIGHT;
  if (sgn(real(p)) < 0)
    return BACK;
  if (sgn(real(p) - 1) > 0)
    return FRONT;
  return ON_SEG;
}

// 垂直,平行
inline bool vertical(L a, L b) { return sgn(dot(vec(a), vec(b))) == 0; }
inline bool parallel(L a, L b) { return sgn(det(vec(a), vec(b))) == 0; }
inline bool eal(L a, L b) { return vertical(a, b) && parallel(a, b); }

// 交差判定
template <bool strict = false> inline bool intersect(const L &l1, const L &l2) {
  if (strict)
    return sgn(det(vec(l1), vec(l2))) != 0;
  return sgn(det(vec(l1), vec(l2))) != 0 || l1 == l2;
}
template <bool strict = false> inline bool intersect(const L &l, const S &s) {
  if (strict)
    det(s.first, vec(l)) * det(s.second, vec(l)) < 0;
  return det(s.first, vec(l)) * det(s.second, vec(l)) <= 0;
}
template <bool strict = false> inline bool intersect(const S &s1, const S &s2) {
  int ccw1 =
      ccw(s1.first, s1.second, s2.first) | ccw(s1.first, s1.second, s2.second);
  int ccw2 =
      ccw(s2.first, s2.second, s1.first) | ccw(s2.first, s2.second, s1.second);
  if (strict)
    return (ccw1 & ccw2) == (LEFT | RIGHT);
  return (ccw1 & ccw2) == (LEFT | RIGHT) || ((ccw1 | ccw2) & ON_SEG);
}
template <bool strict = false> inline bool intersect(const S &s, const P &p) {
  return ccw(s.first, s.second, p) == ON_SEG;
}
template <bool strict = false> inline bool intersect(const L &l, const P &p) {
  return ccw(l.first, l.second, p) == ON_SEG ||
         ccw(l.first, l.second, p) == FRONT ||
         ccw(l.first, l.second, p) == BACK;
}
int intersect(const C &a, const C &b) {
  R dist = sqrt(norm(a.c - b.c)), r1 = a.r + b.r, r2 = abs(a.r - b.r);
  if (sgn(r1 - dist) < 0)
    return 4; // 円が離れている
  if (sgn(r1 - dist) == 0)
    return 3; // 外接
  if (sgn(r2 - dist) < 0 && sgn(dist - r1) < 0)
    return 2; // 交差
  if (sgn(dist - r2) == 0)
    return 1; // 内接
  return 0;   // 内部に含む
}

// 距離
R dist(const S &s, const P &p) {
  P q = projection(s, p);
  if (sgn(dot(s.second - s.first, p - s.first)) <= 0)
    q = s.first;
  if (sgn(dot(s.first - s.second, p - s.second)) <= 0)
    q = s.second;
  return abs(p - q);
}
R dist(const S &a, const S &b) {
  if (intersect(a, b))
    return 0;
  return min({dist(a, b.first), dist(a, b.second), dist(b, a.first),
              dist(b, a.second)});
}
R dist(const L &l, const P &p) {
  P q = projection(l, p);
  return abs(p - q);
}

// 交点 交差判定を先にすること!!!
inline P crosspoint(const L &l1, const L &l2) {
  R ratio = det(vec(l2), l2.first - l1.first) / det(vec(l2), vec(l1));
  return l1.first + vec(l1) * ratio;
}
// ToDo:そもそも交差しないとき
vector<P> crosspoint(C c, L l) {
  R d = dist(l, c.c), r = c.r;
  P m = projection(l, c.c);
  P x = sqrt(r * r - d * d) * vec(l) / abs(vec(l));
  vector<P> ret(2, m);
  ret[0] -= x;
  ret[1] += x;
  if (ret[1] < ret[0])
    swap(ret[0], ret[1]);
  return ret;
}
vector<P> crosspoint(C a, C b) {
  R d = abs(a.c - b.c);
  R t = (a.r * a.r - b.r * b.r + d * d) / 2 / d, h = sqrt(a.r * a.r - t * t);
  P m = t / abs(b.c - a.c) * (b.c - a.c) + a.c;
  auto n_vector = [&](P p) -> P { return P(-p.imag(), p.real()) / abs(p); };
  P n = n_vector(a.c - b.c);
  vector<P> ret(2, m);
  ret[0] -= h * n;
  ret[1] += h * n;
  if (ret[1] < ret[0])
    swap(ret[0], ret[1]);
  return ret;
}

// 面積 頂点が反時計回りに並んでいること
R area(const G &pol) {
  R ret = 0.0;
  REP(i, pol.size()) ret += det(pol[i], pol[(i + 1) % pol.size()]);
  return (ret / 2.0);
}

// 凸性の判定
bool isConvex(const G &pol) {
  REP(i, pol.size()) {
    if (sgn(det(pol[(i + 1) % pol.size()] - pol[i],
                pol[(i + 2) % pol.size()] - pol[i])) < 0) {
      return false;
    }
  }
  return true;
}

// 多角形と点の内包
// 2→in 1→on 0→out
int inPolygon(const G &pol, const P &p) {
  bool in = false;
  for (int i = 0; i < pol.size(); ++i) {
    P a = pol[i] - p, b = pol[(i + 1) % pol.size()] - p;
    if (imag(a) > imag(b))
      swap(a, b);
    if (imag(a) <= 0 && 0 < imag(b) && sgn(det(a, b)) < 0) {
      in = !in;
    }
    if (sgn(det(a, b)) == 0 && sgn(dot(a, b)) <= 0)
      return 1;
  }
  return in ? 2 : 0;
}

// 凸包 3点が一直線上に並ぶときに注意
// 凸包のうち一番左にある頂点の中で一番下の頂点から時計回り
G convex_hull(G ps) {
  int n = ps.size(), k = 0;
  sort(ps.begin(), ps.end());
  G r(2 * n);
  for (int i = 0; i < n; i++) {
    while (k > 1 && sgn(det(r[k - 1] - r[k - 2], ps[i] - r[k - 2])) < 0)
      k--;
    r[k++] = ps[i];
  }
  for (int i = n - 2, t = k; i >= 0; i--) {
    while (k > t && sgn(det(r[k - 1] - r[k - 2], ps[i] - r[k - 2])) < 0)
      k--;
    r[k++] = ps[i];
  }
  r.resize(k - 1);
  return r;
}

/*
3点が与えられたときに円を求める
返り値は{中心のx座標、y座標、半径}
3点が直線上に並んでいるときは{0, 0, -1}を返す
ToDo:見直す
*/
C calcCircle(R x1, R y1, R x2, R y2, R x3, R y3) {
  R ox, oy, a, b, c, d;
  R r1, r2, r3;

  a = x2 - x1;
  b = y2 - y1;
  c = x3 - x1;
  d = y3 - y1;
  R cx, cy, r;
  if ((a && d) || (b && c)) {
    ox = x1 + (d * (a * a + b * b) - b * (c * c + d * d)) / (a * d - b * c) / 2;
    if (b)
      oy = (a * (x1 + x2 - ox - ox) + b * (y1 + y2)) / b / 2;
    else
      oy = (c * (x1 + x3 - ox - ox) + d * (y1 + y3)) / d / 2;
    r1 = sqrt((ox - x1) * (ox - x1) + (oy - y1) * (oy - y1));
    r2 = sqrt((ox - x2) * (ox - x2) + (oy - y2) * (oy - y2));
    r3 = sqrt((ox - x3) * (ox - x3) + (oy - y3) * (oy - y3));
    cx = ox;
    cy = oy;
    r = (r1 + r2 + r3) / 3;
    return {P{cx, cy}, r};
  }

  return {P{0, 0}, -1};
}

// 2点p1, p2を通り、半径がrの円を2つ返す
vector<C> calcCircle(P p1, P p2, R r) {
  // 存在しない
  if (abs(p1 - p2) > 2 * r)
    return {};
  P p3 = {(p1.real() + p2.real()) / 2, (p1.imag() + p2.imag()) / 2};
  R l = abs(p1 - p3);
  P p1p2 = p2 - p1;
  R a = p1p2.real(), b = p1p2.imag();
  R dx1 = b * sqrt((r * r - l * l) / (a * a + b * b)),
    dy1 = a * sqrt((r * r - l * l) / (a * a + b * b));
  return {{{p3.real() + dx1, p3.imag() - dy1}, r},
          {{p3.real() - dx1, p3.imag() + dy1}, r}};
}

P p1[55], p2[55];
R d[55], h[55];
signed main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);

  while (true) {
    int n;
    cin >> n;
    if (!n)
      break;
    S s;
    cin >> s;
    REP(i, n) cin >> p1[i] >> p2[i] >> h[i];

    REP(i, n) {
      d[i] = INF;
      S tmp = S(p1[i], P{p1[i].real(), p2[i].imag()});
      chmin(d[i], dist(s, tmp));
      tmp = S(P{p1[i].real(), p2[i].imag()}, p2[i]);
      chmin(d[i], dist(s, tmp));
      tmp = S(p2[i], P{p2[i].real(), p1[i].imag()});
      chmin(d[i], dist(s, tmp));
      tmp = S(P{p2[i].real(), p1[i].imag()}, p1[i]);
      chmin(d[i], dist(s, tmp));
      if (p1[i].real() <= s.first.real() && s.first.real() <= p2[i].real() &&
          p1[i].imag() <= s.first.imag() && s.first.imag() <= p2[i].imag()) {
        d[i] = 0;
      }
      if (p1[i].real() <= s.second.real() && s.second.real() <= p2[i].real() &&
          p1[i].imag() <= s.second.imag() && s.second.imag() <= p2[i].imag()) {
        d[i] = 0;
      }
    }

    auto check = [&](R r) -> bool {
      REP(i, n) {
        if (r < h[i]) {
          if (r > d[i])
            return false;
        } else {
          R tmp = r * r - (r - h[i]) * (r - h[i]);
          if (tmp > d[i] * d[i])
            return false;
        }
      }
      return true;
    };

    bool flag = false;
    const R dr = 0.001 / 2;
    for (R r = 1000; r >= 0; r -= dr) {
      if (check(r)) {
        cout << fixed << setprecision(9) << r << endl;
        flag = true;
        break;
      }
    }

    if (!flag)
      cout << 0 << endl;
  }

  return 0;
}