Problem p00738 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;

#define EPS 1e-8
#define INF 1e8

typedef complex<double> Point;
namespace std {
bool operator<(const Point &a, const Point &b) {
  return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
}
Point operator/(const Point &p, const double &a) {
  return Point(real(p) / a, imag(p) / a);
}
Point operator*(const Point &p, const double &a) {
  return Point(real(p) * a, imag(p) * a);
}
bool operator==(const Point &a, const Point &b) {
  return real(a) == real(b) && real(a) == real(b);
}
} // namespace std

typedef vector<Point> Polygon;
struct Line : public vector<Point> {
  Line() {}
  Line(const Point &a, const Point &b) {
    push_back(a);
    push_back(b);
  }
};
struct Circle {
  Point c;
  double r;
  Circle() {}
  Circle(const Point &c, double r) : c(c), r(r) {}
};

double dot(const Point &a, const Point &b) { return real(conj(a) * b); }

double cross(const Point &a, const Point &b) { return imag(conj(a) * b); }

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

int ccw(Point a, Point b, Point c) {
  b -= a;
  c -= a;
  if (cross(b, c) > 0)
    return +1;
  if (cross(b, c) < 0)
    return -1;
  if (dot(b, c) < 0)
    return +2;
  if (norm(b) < norm(c))
    return -2;
  return 0;
}

double distancePP(const Point &a, const Point &b) { return abs(a - b); }

bool intersectSS(const Line &s, const Line &t) {
  return ccw(s[0], s[1], t[0]) * ccw(s[0], s[1], t[1]) <= 0 &&
         ccw(t[0], t[1], s[0]) * ccw(t[0], t[1], s[1]) <= 0;
}

bool intersectSP(const Line &s, const Point &p) {
  return abs(s[0] - p) + abs(s[1] - p) - abs(s[1] - s[0]) < EPS;
}

double distanceSP(const Line &s, const Point &p) {
  const Point r = projection(s, p);
  if (intersectSP(s, r))
    return abs(r - p);
  return min(abs(s[0] - p), abs(s[1] - p));
}

bool intersectLL(const Line &l, const Line &m) {
  return abs(cross(l[1] - l[0], m[1] - m[0])) > EPS ||
         abs(cross(l[1] - l[0], m[0] - l[0])) < EPS;
}

bool inPolygon(const Polygon &g, const Point &p) {
  double sum = 0.0;
  int n = g.size();
  for (int i = 0; i < g.size(); i++) {
    int j = (i + 1) % n;
    if (intersectSP(Line(g[i], g[j]), p))
      return true;
    sum += arg((g[j] - p) / (g[i] - p));
  }
  return abs(sum) > 1;
}

int main(void) {
  int N;
  while (cin >> N, N) {
    int miss = 0;
    double sx, sy, ex, ey;
    vector<Point> ps(N, Point(INF, INF));
    cin >> sx >> sy >> ex >> ey;
    Line root = Line(Point(sx, sy), Point(ex, ey));
    for (int i = 0; i < N; i++) {
      double ax, ay, bx, by, h;
      double d = INF;
      cin >> ax >> ay >> bx >> by >> h;
      Polygon g;
      g.push_back(Point(ax, ay));
      g.push_back(Point(bx, ay));
      g.push_back(Point(bx, by));
      g.push_back(Point(ax, by));
      // 内部判定
      if (inPolygon(g, root[0]) || inPolygon(g, root[1]))
        miss = 1;
      // 接触判定
      if (intersectSS(root, Line(Point(ax, ay), Point(bx, ay))))
        miss = 1;
      if (intersectSS(root, Line(Point(bx, ay), Point(bx, by))))
        miss = 1;
      if (intersectSS(root, Line(Point(bx, by), Point(ax, by))))
        miss = 1;
      if (intersectSS(root, Line(Point(ax, by), Point(ax, ay))))
        miss = 1;
      if (miss)
        continue;
      // 最小距離
      for (int j = 0; j < g.size(); j++) {
        d = min(d, distanceSP(root, g[j]));
      }

      d = min(d, distanceSP(Line(Point(ax, ay), Point(bx, ay)), root[0]));
      d = min(d, distanceSP(Line(Point(ax, ay), Point(bx, ay)), root[1]));

      d = min(d, distanceSP(Line(Point(bx, ay), Point(bx, by)), root[0]));
      d = min(d, distanceSP(Line(Point(bx, ay), Point(bx, by)), root[1]));

      d = min(d, distanceSP(Line(Point(bx, by), Point(ax, by)), root[0]));
      d = min(d, distanceSP(Line(Point(bx, by), Point(ax, by)), root[1]));

      d = min(d, distanceSP(Line(Point(ax, by), Point(ax, ay)), root[0]));
      d = min(d, distanceSP(Line(Point(ax, by), Point(ax, ay)), root[1]));
      ps[i] = Point(d, h);
    }
    if (miss) {
      cout << "0" << endl;
      continue;
    }
    double left = 0, right = 10000;
    double ans = 0;
    while (right - left > EPS) {
      double mid = (left + right) / 2;
      double ret = INF;
      for (int i = 0; i < ps.size(); i++) {
        if (imag(ps[i]) <= mid) {
          ret = min(ret, distancePP(Point(0, mid), ps[i]));
        } else {
          ret = min(ret, real(ps[i]));
        }
      }
      if (ret <= mid + EPS)
        right = mid;
      else {
        ans = mid;
        left = mid;
      }
      //			printf("%.4lf -> ret:ans = [%.4lf : %.4lf]\\n",
      //mid, ret, ans);
    }
    printf("%.9lf\\n", ans);
  }
  return 0;
}

Error: WA

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;

#define EPS 1e-8
#define INF 1e8

typedef complex<double> Point;
namespace std {
bool operator<(const Point &a, const Point &b) {
  return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
}
Point operator/(const Point &p, const double &a) {
  return Point(real(p) / a, imag(p) / a);
}
Point operator*(const Point &p, const double &a) {
  return Point(real(p) * a, imag(p) * a);
}
bool operator==(const Point &a, const Point &b) {
  return real(a) == real(b) && real(a) == real(b);
}
} // namespace std

typedef vector<Point> Polygon;
struct Line : public vector<Point> {
  Line() {}
  Line(const Point &a, const Point &b) {
    push_back(a);
    push_back(b);
  }
};
struct Circle {
  Point c;
  double r;
  Circle() {}
  Circle(const Point &c, double r) : c(c), r(r) {}
};

double dot(const Point &a, const Point &b) { return real(conj(a) * b); }

double cross(const Point &a, const Point &b) { return imag(conj(a) * b); }

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

int ccw(Point a, Point b, Point c) {
  b -= a;
  c -= a;
  if (cross(b, c) > 0)
    return +1;
  if (cross(b, c) < 0)
    return -1;
  if (dot(b, c) < 0)
    return +2;
  if (norm(b) < norm(c))
    return -2;
  return 0;
}

double distancePP(const Point &a, const Point &b) { return abs(a - b); }

bool intersectSS(const Line &s, const Line &t) {
  return ccw(s[0], s[1], t[0]) * ccw(s[0], s[1], t[1]) <= 0 &&
         ccw(t[0], t[1], s[0]) * ccw(t[0], t[1], s[1]) <= 0;
}

bool intersectSP(const Line &s, const Point &p) {
  return abs(s[0] - p) + abs(s[1] - p) - abs(s[1] - s[0]) < EPS;
}

double distanceSP(const Line &s, const Point &p) {
  const Point r = projection(s, p);
  if (intersectSP(s, r))
    return abs(r - p);
  return min(abs(s[0] - p), abs(s[1] - p));
}

bool intersectLL(const Line &l, const Line &m) {
  return abs(cross(l[1] - l[0], m[1] - m[0])) > EPS ||
         abs(cross(l[1] - l[0], m[0] - l[0])) < EPS;
}

bool inPolygon(const Polygon &g, const Point &p) {
  double sum = 0.0;
  int n = g.size();
  for (int i = 0; i < g.size(); i++) {
    int j = (i + 1) % n;
    if (intersectSP(Line(g[i], g[j]), p))
      return true;
    sum += arg((g[j] - p) / (g[i] - p));
  }
  return abs(sum) > 1;
}

int main(void) {
  int N;
  while (cin >> N, N) {
    int miss = 0;
    double sx, sy, ex, ey;
    vector<Point> ps(N, Point(INF, INF));
    cin >> sx >> sy >> ex >> ey;
    Line root = Line(Point(sx, sy), Point(ex, ey));

    for (int i = 0; i < N; i++) {
      double ax, ay, bx, by, h;
      double d = INF;
      cin >> ax >> ay >> bx >> by >> h;
      Polygon g;
      g.push_back(Point(ax, ay));
      g.push_back(Point(bx, ay));
      g.push_back(Point(bx, by));
      g.push_back(Point(ax, by));
      // 内部判定
      if (inPolygon(g, root[0]) && inPolygon(g, root[1]))
        miss = 1;
      // 接触判定
      if (intersectSS(root, Line(Point(ax, ay), Point(bx, ay))))
        miss = 1;
      if (intersectSS(root, Line(Point(bx, ay), Point(bx, by))))
        miss = 1;
      if (intersectSS(root, Line(Point(bx, by), Point(ax, by))))
        miss = 1;
      if (intersectSS(root, Line(Point(ax, by), Point(ax, ay))))
        miss = 1;
      if (miss)
        break;

      // 最小距離
      d = min(d, distanceSP(root, Point(ax, ay)));
      d = min(d, distanceSP(root, Point(bx, by)));
      d = min(d, distanceSP(root, Point(ax, by)));
      d = min(d, distanceSP(root, Point(bx, ay)));

      d = min(d, distanceSP(Line(Point(ax, ay), Point(bx, ay)), root[0]));
      d = min(d, distanceSP(Line(Point(ax, ay), Point(bx, ay)), root[1]));

      d = min(d, distanceSP(Line(Point(bx, ay), Point(bx, by)), root[0]));
      d = min(d, distanceSP(Line(Point(bx, ay), Point(bx, by)), root[1]));

      d = min(d, distanceSP(Line(Point(bx, by), Point(ax, by)), root[0]));
      d = min(d, distanceSP(Line(Point(bx, by), Point(ax, by)), root[1]));

      d = min(d, distanceSP(Line(Point(ax, by), Point(ax, ay)), root[0]));
      d = min(d, distanceSP(Line(Point(ax, by), Point(ax, ay)), root[1]));
      ps[i] = Point(d, h);
    }
    if (miss) {
      cout << "0" << endl;
      continue;
    }
    double left = 0, right = 10000;
    double ans = 0;
    while (right - left > EPS) {
      double mid = (left + right) / 2;
      double ret = INF;
      for (int i = 0; i < N; i++) {
        ret = min(ret, distancePP(Point(0, mid), ps[i]));
      }
      if (ret <= mid + EPS)
        right = mid;
      else
        ans = ret, left = mid;
      //			printf("%.4lf -> ret:ans = [%.4lf : %.4lf]\\n",
      //mid, ret, ans);
    }
    printf("%.9lf\\n", ans);
  }
  return 0;
}