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

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

using namespace std;

#define REP(i, x) for (int i = 0; i < (int)(x); i++)
#define REPS(i, x) for (int i = 1; i <= (int)(x); i++)
#define RREP(i, x) for (int i = ((int)(x)-1); i >= 0; i--)
#define RREPS(i, x) for (int i = ((int)(x)); i > 0; i--)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define RFOR(i, c)                                                             \\
  for (__typeof((c).rbegin()) i = (c).rbegin(); i != (c).rend(); i++)
#define ALL(container) (container).begin(), (container).end()
#define RALL(container) (container).rbegin(), (container).rend()
#define SZ(container) ((int)container.size())
#define mp(a, b) make_pair(a, b)
#define pb push_back
#define eb emplace_back
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());
template <class T> ostream &operator<<(ostream &os, const vector<T> &t) {
  os << "[";
  FOR(it, t) {
    if (it != t.begin())
      os << ",";
    os << *it;
  }
  os << "]";
  return os;
}

namespace geom {
#define X real()
#define Y imag()
#define at(i) ((*this)[i])
#define SELF (*this)
enum { TRUE = 1, FALSE = 0, BORDER = -1 };
typedef int BOOL;
typedef long double R;
const R INF = 1e8;
R EPS = 1e-12;
inline int sig(const R &x) { return (abs(x) < EPS ? 0 : x > 0 ? 1 : -1); }
inline BOOL less(const R &x, const R &y) { return sig(x - y) ? x < y : BORDER; }
typedef complex<R> P;
#undef SELF
#undef at
} // namespace geom

using namespace geom;

int f = 0;
namespace std {
bool operator<(const P &a, const P &b) {
  return sig(a.X - b.X) ? a.X < b.X : a.Y + EPS < b.Y;
}
bool operator==(const P &a, const P &b) { return abs(a - b) < EPS; }
istream &operator>>(istream &is, P &p) {
  R x, y;
  is >> x >> y;
  p = P(x, y);
  return is;
}
} // namespace std

int n;

int check(P p, const vector<P> &a, const vector<P> &b) {
  const R PI = 2 * atan2(1, 0);
  vector<pair<R, int>> args(1, make_pair(INF, 0));
  for (auto &q : a) {
    R a = arg(q - p);
    args.eb(a, 0);
    args.eb(a + 2 * PI, 0);
  }
  for (auto &q : b) {
    R a = arg(q - p);
    args.eb(a, 1);
    args.eb(a + 2 * PI, 1);
  }
  sort(ALL(args));
  int j = 0;
  int ans = n - 1;
  int c[2] = {0, 0};
  REP(i, n - 1) {
    while (args[j].first < args[i].first + PI - EPS)
      c[args[j++].second]++;
    if (c[0] == 0 && c[1] == b.size())
      return 1;
    if (c[1] == 0 && c[0] == a.size())
      return 1;
    c[args[i].second]--;
  }
  return 0;
}

int main() {
  cin >> n;
  vector<P> p, q;
  REP(i, n) {
    double x, y;
    cin >> x >> y;
    p.eb(x, y);
  }
  REP(i, n) {
    P t = p.back();
    p.pop_back();
    if (!check(t, p, q)) {
      cout << "Impossible" << endl;
      return 0;
    }
    q.pb(t);
  }
  cout << "Possible" << endl;
  return 0;
}

Error: TLE

Fixed submission:

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

using namespace std;

#define REP(i, x) for (int i = 0; i < (int)(x); i++)
#define ALL(container) (container).begin(), (container).end()
#define pb push_back
#define eb emplace_back

#define X real()
#define Y imag()
#define at(i) ((*this)[i])
typedef long double R;
typedef complex<R> P;
R EPS = 1e-6;

namespace std {
bool operator<(const P &a, const P &b) {
  return abs(a.X - b.X) > EPS ? a.X < b.X : a.Y + EPS < b.Y;
}
bool operator==(const P &a, const P &b) { return abs(a - b) < EPS; }
} // namespace std

inline int sig(const R &x) { return (abs(x) < EPS ? 0 : x > 0 ? 1 : -1); }
inline R norm(const P &p) { return p.X * p.X + p.Y * p.Y; }
inline R inp(const P &a, const P &b) { return (conj(a) * b).X; }
inline R outp(const P &a, const P &b) { return (conj(a) * b).Y; }
inline P unit(const P &p) { return p / abs(p); }
inline P proj(const P &s, const P &t) { return t * inp(s, t) / norm(t); }
inline int ccw(const P &s, const P &t, const P &p, int adv = 0) {
  int res = sig(outp(t - s, p - s));
  if (res || !adv)
    return res;
  if (sig(inp(t - s, p - s)) < 0)
    return -2; // p-s-t
  if (sig(inp(s - t, p - t)) < 0)
    return 2; // s-t-p
  return 0;   // s-p-t
}
struct L : public vector<P> { // line
  L(const P &p1, const P &p2) {
    this->push_back(p1);
    this->push_back(p2);
  }
  L() {}
  P dir() const { return at(1) - at(0); }
};
struct S : public L { // segment
  S(const P &p1, const P &p2) : L(p1, p2) {}
  S() {}
};
inline P crosspoint(const L &l, const L &m) {
  R A = outp(l.dir(), m.dir()), B = outp(l.dir(), l[1] - m[0]);
  if (!sig(abs(A)) && !sig(abs(B)))
    return m[0]; // same line
  return m[0] + B / A * (m[1] - m[0]);
}
struct G : public vector<P> {
  G(size_type size = 0) : vector(size) {}
  S edge(int i) const { return S(at(i), at(i + 1 == size() ? 0 : i + 1)); }

  R area() const {
    R sum = 0;
    REP(i, size()) sum += outp(at(i), at((i + 1) % size()));
    return abs(sum / 2.);
  }
  G convex_hull(bool online = false) {
    if (size() < 2)
      return *this;
    sort(ALL(*this));
    G r;
    r.resize((int)size() * 2);
    int k = 0;
    for (int i = 0; i < size(); r[k++] = at(i++))
      while (k > 1 && ccw(r[k - 2], r[k - 1], at(i)) < 1 - online)
        k--;
    int t = k;
    for (int i = (int)size() - 1; i >= 0; r[k++] = at(i--))
      while (k > t && ccw(r[k - 2], r[k - 1], at(i)) < 1 - online)
        k--;
    r.resize(k - 1);
    return r;
  }
  G cut(const L &l) const {
    G g;
    REP(i, size()) {
      const S &s = edge(i);
      if (ccw(l[0], l[1], s[0], 0) >= 0)
        g.push_back(s[0]);
      if (ccw(l[0], l[1], s[0], 0) * ccw(l[0], l[1], s[1], 0) < 0)
        g.push_back(crosspoint(s, l));
    }
    return g;
  }
  G cut(const G &l) const {
    G g = (*this);
    REP(i, l.size()) { g = g.cut(l.edge(i)); }
    return g;
  }
};

int n;

int check(G a, G b) {
  a = a.convex_hull();
  b = b.convex_hull();
  return b.area() < EPS || a.cut(b).area() < EPS;
}

int main() {
  cin >> n;
  G p, q;
  REP(i, n) {
    double x, y;
    cin >> x >> y;
    p.eb(x, y);
  }
  REP(i, n) {
    q.pb(p.back());
    if (!check(p, q)) {
      cout << "Impossible" << endl;
      return 0;
    }
    p.pop_back();
  }
  cout << "Possible" << endl;
  return 0;
}