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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>

using namespace std;

#define EPS 1e-10
#define equal(a, b) (fabs(a - b) < EPS)

struct Point {
  double x, y;

  Point() {}
  Point(double x, double y) : x(x), y(y) {}

  Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
  Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
  Point operator*(const double &k) const { return Point(x * k, y * k); }
  Point operator/(const double &k) const { return Point(x / k, y / k); }
  bool operator<(const Point &p) const { return x != p.x ? x < p.x : y < p.y; }
};

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

istream &operator>>(istream &is, Point &p) { return is >> p.x >> p.y; }

#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
typedef Point Vector;

int ccw(Point p0, Point p1, Point p2) {
  Vector a = p1 - p0;
  Vector 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;
}

struct Segment {
  Point s, t;
  Segment() {}
  Segment(Point s, Point t) : s(s), t(t) {}
};

bool isIntersectSP(const Segment &s, const Point &p) {
  return equal(ccw(s.s, s.t, p), 0);
}

bool isIntersectSS(const Segment &a, const Segment &b) {
  Point s[2] = {a.s, a.t}, t[2] = {b.s, b.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;
}

#define prev(G, i) (G[(i - 1 + G.size()) % G.size()])
#define curr(G, i) (G[i % G.size()])
#define next(G, i) (G[(i + 1) % G.size()])
typedef vector<Point> Polygon;

bool check(const Polygon &pg, const Point &p) {
  int N = pg.size();
  bool in = false;
  for (int i = 0; i < N; i++) {
    Point a = curr(pg, i) - p, b = next(pg, i) - p;
    if (a.y > b.y) {
      swap(a, b);
    }
    if (a.y <= 0 && 0 < b.y && cross(a, b) > 0) {
      in = !in;
    }
    if (cross(a, b) == 0 && dot(a, b) <= 0) {
      return true;
    }
  }
  return in;
}

bool sortY(Point p1, Point p2) {
  if (p1.y != p2.y) {
    return (p1.y - p2.y < -EPS);
  } else {
    return (p1.x - p2.x < -EPS);
  }
}

Polygon convex_hull(Polygon &ps) {
  int N = ps.size(), j = 0;
  Polygon pg(N * 2);
  sort(ps.begin(), ps.end(), sortY);
  for (int i = 0; i < N; i++, j++) {
    while (j >= 2 && ccw(pg[j - 2], pg[j - 1], ps[i]) == -1) {
      j--;
    }
    pg[j] = ps[i];
  }
  int k = j + 1;
  for (int i = N - 2; i >= 0; i--, j++) {
    while (j >= k && ccw(pg[j - 2], pg[j - 1], ps[i]) == -1) {
      j--;
    }
    pg[j] = ps[i];
  }
  pg.resize(j - 1);
  return pg;
}

bool solve(Polygon &bp, Polygon &wp) {
  int N = bp.size(), M = wp.size();
  if (N == 1 && M == 1) {
    return !(equal(bp[0].x, wp[0].x) && equal(bp[0].y, wp[0].y));
  }
  if (N == 2 && M == 1) {
    Segment s(bp[0], bp[1]);
    return !isIntersectSP(s, wp[0]);
  }
  if (N == 1 && M == 2) {
    Segment s(wp[0], wp[1]);
    return !isIntersectSP(s, bp[0]);
  }
  if (N == 2 && M == 2) {
    Segment s1(bp[0], bp[1]), s2(wp[0], wp[1]);
    return !isIntersectSS(s1, s2);
  }
  bp = convex_hull(bp);
  wp = convex_hull(wp);
  if (N == 1 && M >= 3) {
    return !check(wp, bp[0]);
  }
  if (N >= 3 && M == 1) {
    return !check(bp, wp[0]);
  }
  if (N == 2 && M >= 3) {
    Segment s1(bp[0], bp[1]);
    if (check(wp, bp[0]) || check(wp, bp[1])) {
      return false;
    }
    for (int i = 0; i < M; i++) {
      for (int j = i + 1; j < M; j++) {
        Segment s2(wp[i], wp[j]);
        if (isIntersectSS(s1, s2)) {
          return false;
        }
      }
    }
    return true;
  }
  if (N >= 3 && M == 2) {
    Segment s1(wp[0], wp[1]);
    if (check(bp, wp[0]) || check(bp, wp[1])) {
      return false;
    }
    for (int i = 0; i < N; i++) {
      for (int j = i + 1; j < N; j++) {
        Segment s2(bp[i], bp[j]);
        if (isIntersectSS(s1, s2)) {
          return false;
        }
      }
    }
    return true;
  }
  for (int i = 0; i < N; i++) {
    if (check(wp, bp[i])) {
      return false;
    }
  }
  for (int i = 0; i < M; i++) {
    if (check(bp, wp[i])) {
      return false;
    }
  }
  return true;
}

int main() {
  int N, M;
  while (cin >> N >> M, N) {
    Polygon bp(N), wp(M);
    for (int i = 0; i < N; i++) {
      cin >> bp[i];
    }
    for (int i = 0; i < M; i++) {
      cin >> wp[i];
    }
    cout << (solve(bp, wp) ? "YES" : "NO") << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>

using namespace std;

#define EPS 1e-10
#define equal(a, b) (fabs(a - b) < EPS)

struct Point {
  double x, y;

  Point() {}
  Point(double x, double y) : x(x), y(y) {}

  Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
  Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
  Point operator*(const double &k) const { return Point(x * k, y * k); }
  Point operator/(const double &k) const { return Point(x / k, y / k); }
  bool operator<(const Point &p) const { return x != p.x ? x < p.x : y < p.y; }
};

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

istream &operator>>(istream &is, Point &p) { return is >> p.x >> p.y; }

#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
typedef Point Vector;

int ccw(Point p0, Point p1, Point p2) {
  Vector a = p1 - p0;
  Vector 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;
}

struct Segment {
  Point s, t;
  Segment() {}
  Segment(Point s, Point t) : s(s), t(t) {}
};

bool isIntersectSP(const Segment &s, const Point &p) {
  return equal(ccw(s.s, s.t, p), 0);
}

bool isIntersectSS(const Segment &a, const Segment &b) {
  Point s[2] = {a.s, a.t}, t[2] = {b.s, b.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);
}

#define prev(G, i) (G[(i - 1 + G.size()) % G.size()])
#define curr(G, i) (G[i % G.size()])
#define next(G, i) (G[(i + 1) % G.size()])
typedef vector<Point> Polygon;

bool check(const Polygon &pg, const Point &p) {
  int N = pg.size();
  bool in = false;
  for (int i = 0; i < N; i++) {
    Point a = curr(pg, i) - p, b = next(pg, i) - p;
    if (a.y > b.y) {
      swap(a, b);
    }
    if (a.y <= 0 && 0 < b.y && cross(a, b) > 0) {
      in = !in;
    }
    if (cross(a, b) == 0 && dot(a, b) <= 0) {
      return true;
    }
  }
  return in;
}

bool solve(Polygon &bp, Polygon &wp) {
  int N = bp.size(), M = wp.size();
  if (N == 1 && M == 1) {
    return !(equal(bp[0].x, wp[0].x) && equal(bp[0].y, wp[0].y));
  }
  if (N == 2 && M == 1) {
    Segment s(bp[0], bp[1]);
    return !isIntersectSP(s, wp[0]);
  }
  if (N == 1 && M == 2) {
    Segment s(wp[0], wp[1]);
    return !isIntersectSP(s, bp[0]);
  }
  if (N == 2 && M == 2) {
    Segment s1(bp[0], bp[1]), s2(wp[0], wp[1]);
    return !isIntersectSS(s1, s2);
  }
  if (N == 1 && M >= 3) {
    return !check(wp, bp[0]);
  }
  if (N >= 3 && M == 1) {
    return !check(bp, wp[0]);
  }
  if (N == 2 && M >= 3) {
    Segment s1(bp[0], bp[1]);
    if (check(wp, bp[0]) || check(wp, bp[1])) {
      return false;
    }
    for (int i = 0; i < M; i++) {
      for (int j = i + 1; j < M; j++) {
        Segment s2(wp[i], wp[j]);
        if (isIntersectSS(s1, s2)) {
          return false;
        }
      }
    }
    return true;
  }
  if (N >= 3 && M == 2) {
    Segment s1(wp[0], wp[1]);
    if (check(bp, wp[0]) || check(bp, wp[1])) {
      return false;
    }
    for (int i = 0; i < N; i++) {
      for (int j = i + 1; j < N; j++) {
        Segment s2(bp[i], bp[j]);
        if (isIntersectSS(s1, s2)) {
          return false;
        }
      }
    }
    return true;
  }
  for (int i = 0; i < N; i++) {
    if (check(wp, bp[i])) {
      return false;
    }
  }
  for (int i = 0; i < M; i++) {
    if (check(bp, wp[i])) {
      return false;
    }
  }
  for (int i = 0; i < N; i++) {
    for (int j = i + 1; j < N; j++) {
      for (int k = 0; k < M; k++) {
        for (int l = k + 1; l < M; l++) {
          Segment s1(bp[i], bp[j]), s2(wp[k], wp[l]);
          if (isIntersectSS(s1, s2)) {
            return false;
          }
        }
      }
    }
  }
  return true;
}

int main() {
  int N, M;
  while (cin >> N >> M, (N | M)) {
    Polygon bp(N), wp(M);
    for (int i = 0; i < N; i++) {
      cin >> bp[i];
    }
    for (int i = 0; i < M; i++) {
      cin >> wp[i];
    }
    cout << (solve(bp, wp) ? "YES" : "NO") << endl;
  }
  return 0;
}