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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <iomanip>
#include <iostream>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define EPS (1e-10)
#define inf (1 << 29)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define equals(a, b) (fabs((a) - (b)) < EPS)

using namespace std;

class Point {
public:
  double x, y;

  Point(double x = -inf, double y = -inf) : x(x), y(y) {}

  Point operator+(Point p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
  Point operator*(double a) { return Point(a * x, a * y); }
  Point operator/(double a) { return Point(x / a, y / a); } // ※イケメンに限る
};

struct Segment {
  Point p1, p2;
  Segment(Point p1 = Point(), Point p2 = Point()) : p1(p1), p2(p2) {}
};
typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

double dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }
double cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }

double norm(Point a) { return a.x * a.x + a.y * a.y; }

double abs(Point a) { return sqrt(norm(a)); }

int ccw(Point p0, Point p1, Point p2) {
  Point a = p1 - p0;
  Point b = p2 - p0;
  if (cross(a, b) > EPS)
    return COUNTER_CLOCKWISE;
  if (cross(a, b) < -EPS)
    return CLOCKWISE;
  if (dot(a, b) < -EPS)
    return ONLINE_BACK;
  if (norm(a) < norm(b))
    return ONLINE_FRONT;
  return ON_SEGMENT;
}

double getDistanceLP(Line s, Point p) {
  return abs(cross(s.p2 - s.p1, p - s.p1)) / abs(s.p2 - s.p1);
}

double getDistanceSP(Segment s, Point p) {
  if (dot(s.p2 - s.p1, p - s.p1) < 0.0)
    return abs(p - s.p1);
  if (dot(s.p1 - s.p2, p - s.p2) < 0.0)
    return abs(p - s.p2);
  return getDistanceLP(s, p);
}

struct Circle {
  Point p;
  double r;
  Circle(Point p = Point(), double r = inf) : p(p), r(r) {}
};

bool isIntersect(Point p1, Point p2, Point p3, Point p4) {
  return (ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 &&
          ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0);
}

bool isIntersect(Segment s1, Segment s2) {
  return isIntersect(s1.p1, s1.p2, s2.p1, s2.p2);
}

// cross product of pq and pr
double cross3p(Point p, Point q, Point r) {
  return (r.x - q.x) * (p.y - q.y) - (r.y - q.y) * (p.x - q.x);
}

// returns true if point r is on the same line as the line pq
bool collinear(Point p, Point q, Point r) {
  return fabs(cross3p(p, q, r)) < EPS;
}

// returns true if point t is on the left side of line pq
bool ccwtest(Point p, Point q, Point r) {
  return cross3p(p, q, r) > 0; // can be modified to accept collinear points
}

bool onSegment(Point p, Point q, Point r) {
  return collinear(p, q, r) &&
         equals(sqrt(pow(p.x - r.x, 2) + pow(p.y - r.y, 2)) +
                    sqrt(pow(r.x - q.x, 2) + pow(r.y - q.y, 2)),
                sqrt(pow(p.x - q.x, 2) + pow(p.y - q.y, 2)));
}

bool isConvex(vector<Point> p) {
  int sz = (int)p.size();

  if (sz < 3)
    return false; // boundary case, we treat a point or a line as not convex
  bool isLeft = ccwtest(p[0], p[1], p[2]);

  for (int i = 1; i < (int)p.size(); i++)
    if (ccwtest(p[i], p[(i + 1) % sz], p[(i + 2) % sz]) != isLeft)
      return false;

  return true;
}

double angle(Point a, Point b, Point c) {
  double ux = b.x - a.x, uy = b.y - a.y;
  double vx = c.x - a.x, vy = c.y - a.y;
  return acos((ux * vx + uy * vy) /
              sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy)));
}

// 多角形poly内（線分上も含む）に点pが存在するかどうは判定する
bool inPolygon(Polygon poly, Point p) {
  if ((int)poly.size() == 0)
    return false;

  // polyの最後の要素 = polyの最初の要素 であることが前提

  // そうでない場合は
  rep(i, poly.size()) if (onSegment(poly[i], poly[(i + 1) % poly.size()],
                                    p)) return true;
  double sum = 0;
  for (int i = 0; i < (int)poly.size(); i++) {
    if (cross3p(p, poly[i], poly[(i + 1) % poly.size()]) < 0)
      sum -= angle(p, poly[i], poly[(i + 1) % poly.size()]);
    else
      sum += angle(p, poly[i], poly[(i + 1) % poly.size()]);
  }
  return (fabs(sum - 2 * M_PI) < EPS || fabs(sum + 2 * M_PI) < EPS);
}

Point project(Segment s, Point p) {
  Vector base = s.p2 - s.p1;
  double t = dot(p - s.p1, base) / norm(base);
  return s.p1 + base * t;
}

double getDistance(Segment s1, Segment s2) {
  if (isIntersect(s1, s2))
    return 0;
  return min(min(getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2)),
             min(getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2)));
}
//-------------------------------
bool intersectLL(Line l, Line m) {
  return abs(cross(l.p2 - l.p1, m.p2 - m.p1)) > EPS || // non-parallel
         abs(cross(l.p2 - l.p1, m.p1 - l.p1)) < EPS;   // same line
}
bool intersectLS(Line l, Line s) {
  return cross(l.p2 - l.p1, s.p1 - l.p1) * // s[0] is left of l
             cross(l.p2 - l.p1, s.p2 - l.p1) <
         EPS; // s[1] is right of l
}
bool intersectLP(Line l, Point p) {
  return abs(cross(l.p2 - p, l.p1 - p)) < EPS;
}
bool intersectSS(Line s, Line t) {
  return ccw(s.p1, s.p2, t.p1) * ccw(s.p1, s.p2, t.p2) <= 0 &&
         ccw(t.p1, t.p2, s.p1) * ccw(t.p1, t.p2, s.p2) <= 0;
}
bool intersectSP(Line s, Point p) {
  return abs(s.p1 - p) + abs(s.p2 - p) - abs(s.p2 - s.p1) <
         EPS; // triangle inequality
}

Point projection(Line l, Point p) {
  double t = dot(p - l.p1, l.p1 - l.p2) / norm(l.p1 - l.p2);
  return l.p1 + (l.p1 - l.p2) * t;
}
Point reflection(Line l, Point p) { return p + (projection(l, p) - p) * 2; }
double distanceLP(Line l, Point p) { return abs(p - projection(l, p)); }
double distanceLL(Line l, Line m) {
  return intersectLL(l, m) ? 0 : distanceLP(l, m.p1);
}

double distanceLS(Line l, Line s) {
  if (intersectLS(l, s))
    return 0;
  return min(distanceLP(l, s.p1), distanceLP(l, s.p2));
}
double distanceSP(Line s, Point p) {
  Point r = projection(s, p);
  if (intersectSP(s, r))
    return abs(r - p);
  return min(abs(s.p1 - p), abs(s.p2 - p));
}

double distanceSS(Line s, Line t) {
  if (intersectSS(s, t))
    return 0;
  return min(min(distanceSP(s, t.p1), distanceSP(s, t.p2)),
             min(distanceSP(t, s.p1), distanceSP(t, s.p2)));
}
Point crosspoint(Line l, Line m) {
  double A = cross(l.p2 - l.p1, m.p2 - m.p1);
  double B = cross(l.p2 - l.p1, l.p2 - m.p1);
  if (abs(A) < EPS && abs(B) < EPS)
    return m.p1; // same line
  if (abs(A) < EPS)
    assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m.p1 + (m.p2 - m.p1) * (B / A);
}
//------------------------------------------^^^

struct Obj {
  vector<Point> ps;
  double h;
  Obj(Point ps1 = Point(), Point ps2 = Point(), double h = -inf) : h(h) {
    ps.clear();
    ps.resize(4);
    ps[0].x = ps1.x, ps[0].y = ps1.y;
    ps[1].x = ps1.x, ps[1].y = ps2.y;
    ps[2].x = ps2.x, ps[2].y = ps2.y;
    ps[3].x = ps2.x, ps[3].y = ps1.y;
  }
};
int N;
Point s, e;

int main() {

  while (cin >> N, N) {
    cin >> s.x >> s.y >> e.x >> e.y;

    Obj vec;
    Circle c(s);
    Segment seg(s, e);
    rep(i, N) {
      Point a, b;
      double h;
      cin >> a.x >> a.y >> b.x >> b.y >> h;
      if (c.r == 0)
        continue;
      vec = Obj(a, b, h);
      rep(j, 4) {
        if (isIntersect(seg, Segment(vec.ps[j], vec.ps[(j + 1) % 4]))) {
          c.r = 0;
          break;
        }
      }

      if (inPolygon(vec.ps, s) || inPolygon(vec.ps, e)) {
        c.r = 0;
        continue;
      }

      rep(j, 4) {
        double w = distanceSS(seg, Segment(vec.ps[j], vec.ps[(j + 1) % 4]));
        // double w = getDistance(seg,Segment(vec.ps[j],vec.ps[(j+1)%4]));
        double dist = (h * h + w * w) / (2.0 * h);
        if (!equals(w, h) && w < h)
          dist = w;

        c.r = min(c.r, dist);
      }
    }
    cout << setiosflags(ios::fixed) << setprecision(10) << c.r << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <iomanip>
#include <iostream>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define EPS (1e-10)
#define inf (1 << 29)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define equals(a, b) (fabs((a) - (b)) < EPS)

using namespace std;

class Point {
public:
  double x, y;

  Point(double x = -inf, double y = -inf) : x(x), y(y) {}

  Point operator+(Point p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
  Point operator*(double a) { return Point(a * x, a * y); }
  Point operator/(double a) { return Point(x / a, y / a); } // ※イケメンに限る
};

struct Segment {
  Point p1, p2;
  Segment(Point p1 = Point(), Point p2 = Point()) : p1(p1), p2(p2) {}
};
typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

double dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }
double cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }

double norm(Point a) { return a.x * a.x + a.y * a.y; }

double abs(Point a) { return sqrt(norm(a)); }

int ccw(Point p0, Point p1, Point p2) {
  Point a = p1 - p0;
  Point b = p2 - p0;
  if (cross(a, b) > EPS)
    return COUNTER_CLOCKWISE;
  if (cross(a, b) < -EPS)
    return CLOCKWISE;
  if (dot(a, b) < -EPS)
    return ONLINE_BACK;
  if (norm(a) < norm(b))
    return ONLINE_FRONT;
  return ON_SEGMENT;
}

double getDistanceLP(Line s, Point p) {
  return abs(cross(s.p2 - s.p1, p - s.p1)) / abs(s.p2 - s.p1);
}

double getDistanceSP(Segment s, Point p) {
  if (dot(s.p2 - s.p1, p - s.p1) < 0.0)
    return abs(p - s.p1);
  if (dot(s.p1 - s.p2, p - s.p2) < 0.0)
    return abs(p - s.p2);
  return getDistanceLP(s, p);
}

struct Circle {
  Point p;
  double r;
  Circle(Point p = Point(), double r = inf) : p(p), r(r) {}
};

bool isIntersect(Point p1, Point p2, Point p3, Point p4) {
  return (ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 &&
          ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0);
}

bool isIntersect(Segment s1, Segment s2) {
  return isIntersect(s1.p1, s1.p2, s2.p1, s2.p2);
}

// cross product of pq and pr
double cross3p(Point p, Point q, Point r) {
  return (r.x - q.x) * (p.y - q.y) - (r.y - q.y) * (p.x - q.x);
}

// returns true if point r is on the same line as the line pq
bool collinear(Point p, Point q, Point r) {
  return fabs(cross3p(p, q, r)) < EPS;
}

// returns true if point t is on the left side of line pq
bool ccwtest(Point p, Point q, Point r) {
  return cross3p(p, q, r) > 0; // can be modified to accept collinear points
}

bool onSegment(Point p, Point q, Point r) {
  return collinear(p, q, r) &&
         equals(sqrt(pow(p.x - r.x, 2) + pow(p.y - r.y, 2)) +
                    sqrt(pow(r.x - q.x, 2) + pow(r.y - q.y, 2)),
                sqrt(pow(p.x - q.x, 2) + pow(p.y - q.y, 2)));
}

bool isConvex(vector<Point> p) {
  int sz = (int)p.size();

  if (sz < 3)
    return false; // boundary case, we treat a point or a line as not convex
  bool isLeft = ccwtest(p[0], p[1], p[2]);

  for (int i = 1; i < (int)p.size(); i++)
    if (ccwtest(p[i], p[(i + 1) % sz], p[(i + 2) % sz]) != isLeft)
      return false;

  return true;
}

double angle(Point a, Point b, Point c) {
  double ux = b.x - a.x, uy = b.y - a.y;
  double vx = c.x - a.x, vy = c.y - a.y;
  return acos((ux * vx + uy * vy) /
              sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy)));
}

// 多角形poly内（線分上も含む）に点pが存在するかどうは判定する
bool inPolygon(Polygon poly, Point p) {
  if ((int)poly.size() == 0)
    return false;

  // polyの最後の要素 = polyの最初の要素 であることが前提

  // そうでない場合は
  rep(i, poly.size()) if (onSegment(poly[i], poly[(i + 1) % poly.size()],
                                    p)) return true;
  double sum = 0;
  for (int i = 0; i < (int)poly.size(); i++) {
    if (cross3p(p, poly[i], poly[(i + 1) % poly.size()]) < 0)
      sum -= angle(p, poly[i], poly[(i + 1) % poly.size()]);
    else
      sum += angle(p, poly[i], poly[(i + 1) % poly.size()]);
  }
  return (fabs(sum - 2 * M_PI) < EPS || fabs(sum + 2 * M_PI) < EPS);
}

Point project(Segment s, Point p) {
  Vector base = s.p2 - s.p1;
  double t = dot(p - s.p1, base) / norm(base);
  return s.p1 + base * t;
}

double getDistance(Segment s1, Segment s2) {
  if (isIntersect(s1, s2))
    return 0;
  return min(min(getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2)),
             min(getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2)));
}

struct Obj {
  vector<Point> ps;
  double h;
  Obj(Point ps1 = Point(), Point ps2 = Point(), double h = -inf) : h(h) {
    ps.clear();
    ps.resize(4);
    ps[0].x = ps1.x, ps[0].y = ps1.y;
    ps[1].x = ps1.x, ps[1].y = ps2.y;
    ps[2].x = ps2.x, ps[2].y = ps2.y;
    ps[3].x = ps2.x, ps[3].y = ps1.y;
  }
};
int N;
Point s, e;

int main() {

  while (cin >> N, N) {
    cin >> s.x >> s.y >> e.x >> e.y;
    Obj vec;
    Circle c(s);
    Segment seg(s, e);
    rep(i, N) {
      Point a, b;
      double h;
      cin >> a.x >> a.y >> b.x >> b.y >> h;
      if (c.r == 0)
        continue;
      vec = Obj(a, b, h);
      rep(j, 4) {
        if (isIntersect(seg, Segment(vec.ps[j], vec.ps[(j + 1) % 4]))) {
          c.r = 0;
          break;
        }
      }

      if (inPolygon(vec.ps, s) || inPolygon(vec.ps, e)) {
        c.r = 0;
        break;
      }

      rep(j, 4) {
        /*
        Point p = project(line,vec[i].ps[j]);
        cout << "on point = " << p.x << "," << p.y << endl;
        c.p = p;
        */
        double w = getDistance(seg, Segment(vec.ps[j], vec.ps[(j + 1) % 4]));
        // cout << "w = "<< w << endl;
        // if(equals(w,h) || w < h)continue;

        double dist = (h * h + w * w) / (2.0 * h);
        // cout <<"the distance is " << dist << endl;
        c.r = min(c.r, dist);
        // cout << "c.r = " << c.r << endl;
      }

      // cout << endl;
    }
    cout << setiosflags(ios::fixed) << setprecision(10) << c.r << endl;
  }
  return 0;
}