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

#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <iostream>
#include <set>
#include <vector>

#define ERR 0x00
#define FRONT 0x01
#define RIGHT 0x02
#define BACK 0x04
#define LEFT 0x08
#define OVER 0x10

#define FOR(i, o)                                                              \\
  for (__typeof((o).begin()) i = (o).begin(); i != (o).end(); ++i)
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define NEXT(i, n) ((i + 1) % n)
typedef long double elem;

using namespace std;
typedef complex<elem> point, vec;
typedef pair<point, point> line, seg, pp;

const elem pi = 2 * acos(0.0);
const elem eps = 1.0e-6;
// #define ARGEPS(l) (0.2/(l))
// const elem argeps = 1.0e-1;

point origin(0, 0);

bool eq(elem a, elem b) { return abs(a - b) < eps; }
bool lt(elem a, elem b) { return !eq(a, b) && a < b; }
bool leq(elem a, elem b) { return eq(a, b) || a < b; }
bool gt(elem a, elem b) { return !eq(a, b) && a > b; }
bool geq(elem a, elem b) { return eq(a, b) || a > b; }
bool ltz(elem a) { return lt(a, 0); }
bool gtz(elem a) { return gt(a, 0); }
bool eqv(vec a, vec b) {
  return eq(a.real(), b.real()) && eq(a.imag(), b.imag());
}
bool far(point a, point b) { return gtz(abs(b - a)); }
bool near(point a, point b) { return leq(abs(b - a), 0); }
elem dot(vec a, vec b) { return (a.real() * b.real() + a.imag() * b.imag()); }
elem cross(vec a, vec b) { return (a.real() * b.imag() - a.imag() * b.real()); }
elem len(vec a) { return abs(a); }
elem arg(vec a, vec b) { return acos(dot(a, b) / (len(a) * len(b))); }
point rot(point p, elem theta) { return p * exp(point(0, theta)); }
elem dist(point a, point b) { return abs(a - b); }
elem dist_l(point a1, point a2, point x) {
  return abs(cross(a2 - a1, x - a1)) / abs(a2 - a1);
}
elem dist_seg(point a1, point a2, point x) {
  if (ltz(dot(a2 - a1, x - a1)))
    return abs(x - a1);
  if (ltz(dot(a1 - a2, x - a2)))
    return abs(x - a2);
  return dist_l(a1, a2, x);
}

struct circle {
  elem r;
  point c;
  circle() : r(0), c(origin) {}
  circle(elem r, point c) : r(r), c(c) {}
  bool inCircle(point t) const { return leq(abs(t - c), r); }
};

int ccw(point a, point b, point x) {
  vec vb = b - a;
  vec vx = x - a;
  elem z = cross(vb, vx);

  if (eq(abs(vb), 0))
    return ERR;

  if (eq(z, 0)) {
    elem d_ab = dist(a, b);
    elem d_bx = dist(b, x);
    elem d_ax = dist(a, x);
    if (eq(d_ab, d_ax + d_bx))
      return OVER;
    if (gt(d_ax, d_ab) && gt(d_ax, d_bx))
      return FRONT;
    if (gt(d_bx, d_ab) && gt(d_bx, d_ax))
      return BACK;
  } else if (gtz(z))
    return LEFT;
  else if (ltz(z))
    return RIGHT;
  return ERR;
}
vec uvec(vec a) { return a / abs(a); }
vec normr(vec a) { return a * vec(0, -1); }
vec norml(vec a) { return a * vec(0, 1); }
vec unormr(vec a) { return uvec(normr(a)); }
vec unorml(vec a) { return uvec(norml(a)); }
bool prll(point a1, point a2, point b1, point b2) {
  return eq(cross(a2 - a1, b2 - b1), 0);
}
bool prll(vec v1, vec v2) { return eq(cross(v1, v2), 0); }
point intersection_seg(point a1, point a2, point b1, point b2) {
  elem d1 = dist_l(b1, b2, a1);
  elem d2 = dist_l(b1, b2, a2);
  elem t = d1 / (d1 + d2);
  return a1 + t * (a2 - a1);
}
bool intersected_l(point a1, point a2, point b1, point b2) {
  return !prll(a1, a2, b1, b2);
}
point intersection_l(point a1, point a2, point b1, point b2) {
  vec a = a2 - a1;
  vec b = b2 - b1;
  return a1 + a * (cross(b, b1 - a1) / cross(b, a));
}
bool intersection_l(line a, line b, point &ret) {
  if (intersected_l(a.first, a.second, b.first, b.second)) {
    ret = intersection_l(a.first, a.second, b.first, b.second);
  } else {
    return false;
  }
  return true;
}
bool intersection_circle(circle c, line l, pp &ret) {
  vec v(l.second - l.first);
  v = norml(v);
  point intersection;
  if (intersection_l(l, line(c.c, v + c.c), intersection)) {
    if (c.inCircle(intersection)) {
      elem k =
          sqrt(pow(c.r, (elem)2.0) - pow(dist(intersection, c.c), (elem)2.0));
      vec cr = k * unormr(v);
      vec cl = k * unorml(v);
      ret.first = cl + intersection;
      ret.second = cr + intersection;
      return true;
    }
  }
  return false;
}
int intersection_circle_seg(circle c, seg l, pp &ret) {
  int num = 0;
  pp ret_cand;
  if (intersection_circle(c, l, ret_cand)) {
    num = 0;
    if (ccw(l.first, l.second, ret_cand.first) == OVER) {
      ret.first = ret_cand.first;
      ++num;
    }
    if (ccw(l.first, l.second, ret_cand.second) == OVER) {
      if (num == 0)
        ret.first = ret_cand.second;
      else
        ret.second = ret_cand.second;
      ++num;
    }
  }
  return num;
}
struct field {
  elem len;
  elem total_rot;
  elem max_rot;
  point l, c, r;
  vector<point> wall;

  bool cannotRotateBar() {
    int n = wall.size();
    if (leq(max_rot, total_rot))
      return true;
    return false;
  }
  bool rotateBar(int seq) {
    int n = wall.size();
    bool ret = true;
    elem rotted = 0;
    elem floatingArg = 0;
    elem nfloatingArg = 1;
    elem minArg = 3 * pi;
    elem minArgs[2] = {3 * pi, 3 * pi};
    elem maxDist = 0;
    point nl = l;
    point nc = c;
    point nr = r;

    point pa[] = {l, r};

    REP(k, 2) {
      if (far(pa[k], c)) {
        vec base = pa[k] - c;
        vector<point> cand;
        getCand(dist(pa[k], c), cand);
        for (int i = 0; i < cand.size(); ++i) {
          vec v = cand[i] - c;
          elem Arg = arg(v, base);
          if (eq(Arg, 0))
            continue;
          if (ccw(pa[k], c, cand[i]) & RIGHT)
            Arg = 2 * pi - Arg;
          if (gt(total_rot + Arg, max_rot))
            Arg = max_rot - total_rot;
          if (leq(Arg, minArg)) {
            if (eq(Arg, minArg)) {
              elem d = dist(c, cand[i]);
              if (leq(d, maxDist)) {
                continue;
              }
              maxDist = d;
            }

            minArg = Arg;
            minArgs[k] = min(minArgs[k], minArg);
            nc = cand[i];
            nl = c + rot(l - c, -Arg);
            nr = c + rot(r - c, -Arg);
            rotted = Arg;
          }
        }
      }
    }
    total_rot += rotted;
    if ((near(l, c) || near(r, c))) {
      REP(i, n) {
        line wl(wall[i], wall[NEXT(i, n)]);
        if (ccw(wl.first, wl.second, c) & OVER && gtz(abs(wl.first - c))) {
          if (leq(arg(vec(nc - c), vec(wl.first - c)), pi / 2.0))
            ret = false;
        }
      }
    }
    if (far(c, r) && far(c, l)) {
      REP(i, n) {
        line wl(wall[i], wall[NEXT(i, n)]);
        if (ccw(wl.first, wl.second, l) & OVER) {
          floatingArg = minArgs[1];  // right float
          nfloatingArg = minArgs[0]; // left touched
          break;
        }
        if (ccw(wl.first, wl.second, r) & OVER) {
          floatingArg = minArgs[0];  // left float
          nfloatingArg = minArgs[1]; // right touched
          break;
        }
      }
      if (leq(nfloatingArg, floatingArg)) {
        ret = false;
      }
    }
    c = nc;
    l = nl;
    r = nr;
    return ret;
  }
  void getCand(elem r, vector<point> &ret) {
    int n = wall.size();
    circle C(r, c);
    REP(i, n) {
      if (C.inCircle(wall[i])) {
        ret.push_back(wall[i]);
      }
      pp circle_is;
      int num =
          intersection_circle_seg(C, seg(wall[i], wall[NEXT(i, n)]), circle_is);
      if (num >= 1)
        ret.push_back(circle_is.first);
      if (num >= 2)
        ret.push_back(circle_is.second);
    }
  }
};

int main() {
  while (true) {
    elem L, R;
    int N;
    field F;

    scanf("%Lf%Lf%d", &L, &R, &N);
    if (L == 0 && R == 0 && N == 0)
      break;

    F.len = L;
    F.max_rot = 2 * pi * R;
    F.total_rot = 0;
    F.l = F.c = origin;
    F.r = point(0, L - 0.00001);

    for (int i = 0; i < N; ++i) {
      int x, y;
      scanf("%d%d", &x, &y);
      point p((elem)x, (elem)y);
      F.wall.push_back(p);
    }

    int seq = 0;
    while (!F.cannotRotateBar()) {
      if (!F.rotateBar(seq))
        break;
      ++seq;
    }
    printf("%.15Lf %.15Lf\\n", F.l.real(), F.l.imag());
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <iostream>
#include <set>
#include <vector>

#define ERR 0x00
#define FRONT 0x01
#define RIGHT 0x02
#define BACK 0x04
#define LEFT 0x08
#define OVER 0x10

#define FOR(i, o)                                                              \\
  for (__typeof((o).begin()) i = (o).begin(); i != (o).end(); ++i)
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define NEXT(i, n) ((i + 1) % n)
typedef long double elem;

using namespace std;
typedef complex<elem> point, vec;
typedef pair<point, point> line, seg, pp;

const elem pi = 2 * acos(0.0);
const elem eps = 1.0e-5;
// #define ARGEPS(l) (0.2/(l))
// const elem argeps = 1.0e-1;

point origin(0, 0);

bool eq(elem a, elem b) { return abs(a - b) < eps; }
bool lt(elem a, elem b) { return !eq(a, b) && a < b; }
bool leq(elem a, elem b) { return eq(a, b) || a < b; }
bool gt(elem a, elem b) { return !eq(a, b) && a > b; }
bool geq(elem a, elem b) { return eq(a, b) || a > b; }
bool ltz(elem a) { return lt(a, 0); }
bool gtz(elem a) { return gt(a, 0); }
bool eqv(vec a, vec b) {
  return eq(a.real(), b.real()) && eq(a.imag(), b.imag());
}
bool far(point a, point b) { return gtz(abs(b - a)); }
bool near(point a, point b) { return leq(abs(b - a), 0); }
elem dot(vec a, vec b) { return (a.real() * b.real() + a.imag() * b.imag()); }
elem cross(vec a, vec b) { return (a.real() * b.imag() - a.imag() * b.real()); }
elem len(vec a) { return abs(a); }
elem arg(vec a, vec b) { return acos(dot(a, b) / (len(a) * len(b))); }
point rot(point p, elem theta) { return p * exp(point(0, theta)); }
elem dist(point a, point b) { return abs(a - b); }
elem dist_l(point a1, point a2, point x) {
  return abs(cross(a2 - a1, x - a1)) / abs(a2 - a1);
}
elem dist_seg(point a1, point a2, point x) {
  if (ltz(dot(a2 - a1, x - a1)))
    return abs(x - a1);
  if (ltz(dot(a1 - a2, x - a2)))
    return abs(x - a2);
  return dist_l(a1, a2, x);
}

struct circle {
  elem r;
  point c;
  circle() : r(0), c(origin) {}
  circle(elem r, point c) : r(r), c(c) {}
  bool inCircle(point t) const { return leq(abs(t - c), r); }
};

int ccw(point a, point b, point x) {
  vec vb = b - a;
  vec vx = x - a;
  elem z = cross(vb, vx);

  if (eq(abs(vb), 0))
    return ERR;

  if (eq(z, 0)) {
    elem d_ab = dist(a, b);
    elem d_bx = dist(b, x);
    elem d_ax = dist(a, x);
    if (eq(d_ab, d_ax + d_bx))
      return OVER;
    if (gt(d_ax, d_ab) && gt(d_ax, d_bx))
      return FRONT;
    if (gt(d_bx, d_ab) && gt(d_bx, d_ax))
      return BACK;
  } else if (gtz(z))
    return LEFT;
  else if (ltz(z))
    return RIGHT;
  return ERR;
}
vec uvec(vec a) { return a / abs(a); }
vec normr(vec a) { return a * vec(0, -1); }
vec norml(vec a) { return a * vec(0, 1); }
vec unormr(vec a) { return uvec(normr(a)); }
vec unorml(vec a) { return uvec(norml(a)); }
bool prll(point a1, point a2, point b1, point b2) {
  return eq(cross(a2 - a1, b2 - b1), 0);
}
bool prll(vec v1, vec v2) { return eq(cross(v1, v2), 0); }
point intersection_seg(point a1, point a2, point b1, point b2) {
  elem d1 = dist_l(b1, b2, a1);
  elem d2 = dist_l(b1, b2, a2);
  elem t = d1 / (d1 + d2);
  return a1 + t * (a2 - a1);
}
bool intersected_l(point a1, point a2, point b1, point b2) {
  return !prll(a1, a2, b1, b2);
}
point intersection_l(point a1, point a2, point b1, point b2) {
  vec a = a2 - a1;
  vec b = b2 - b1;
  return a1 + a * (cross(b, b1 - a1) / cross(b, a));
}
bool intersection_l(line a, line b, point &ret) {
  if (intersected_l(a.first, a.second, b.first, b.second)) {
    ret = intersection_l(a.first, a.second, b.first, b.second);
  } else {
    return false;
  }
  return true;
}
bool intersection_circle(circle c, line l, pp &ret) {
  vec v(l.second - l.first);
  v = norml(v);
  point intersection;
  if (intersection_l(l, line(c.c, v + c.c), intersection)) {
    if (c.inCircle(intersection)) {
      elem k =
          sqrt(pow(c.r, (elem)2.0) - pow(dist(intersection, c.c), (elem)2.0));
      vec cr = k * unormr(v);
      vec cl = k * unorml(v);
      ret.first = cl + intersection;
      ret.second = cr + intersection;
      return true;
    }
  }
  return false;
}
int intersection_circle_seg(circle c, seg l, pp &ret) {
  int num = 0;
  pp ret_cand;
  if (intersection_circle(c, l, ret_cand)) {
    num = 0;
    if (ccw(l.first, l.second, ret_cand.first) == OVER) {
      ret.first = ret_cand.first;
      ++num;
    }
    if (ccw(l.first, l.second, ret_cand.second) == OVER) {
      if (num == 0)
        ret.first = ret_cand.second;
      else
        ret.second = ret_cand.second;
      ++num;
    }
  }
  return num;
}
struct field {
  elem len;
  elem total_rot;
  elem max_rot;
  point l, c, r;
  vector<point> wall;

  bool cannotRotateBar() {
    int n = wall.size();
    if (leq(max_rot, total_rot))
      return true;
    return false;
  }
  bool rotateBar(int seq) {
    int n = wall.size();
    bool ret = true;
    elem rotted = 0;
    elem floatingArg = 0;
    elem nfloatingArg = 1;
    elem minArg = 3 * pi;
    elem minArgs[2] = {3 * pi, 3 * pi};
    elem maxDist = 0;
    point nl = l;
    point nc = c;
    point nr = r;

    point pa[] = {l, r};

    REP(k, 2) {
      if (far(pa[k], c)) {
        vec base = pa[k] - c;
        vector<point> cand;
        getCand(dist(pa[k], c), cand);
        for (int i = 0; i < cand.size(); ++i) {
          vec v = cand[i] - c;
          elem Arg = arg(v, base);
          if (eq(Arg, 0))
            continue;
          if (ccw(pa[k], c, cand[i]) & RIGHT)
            Arg = 2 * pi - Arg;
          if (gt(total_rot + Arg, max_rot))
            Arg = max_rot - total_rot;
          if (leq(Arg, minArg)) {
            if (eq(Arg, minArg)) {
              elem d = dist(c, cand[i]);
              if (leq(d, maxDist)) {
                continue;
              }
              maxDist = d;
            }

            minArg = Arg;
            minArgs[k] = min(minArgs[k], minArg);
            nc = cand[i];
            nl = c + rot(l - c, -Arg);
            nr = c + rot(r - c, -Arg);
            rotted = Arg;
          }
        }
      }
    }
    total_rot += rotted;
    if ((near(l, c) || near(r, c))) {
      REP(i, n) {
        line wl(wall[i], wall[NEXT(i, n)]);
        if (ccw(wl.first, wl.second, c) & OVER && gtz(abs(wl.first - c))) {
          if (leq(arg(vec(nc - c), vec(wl.first - c)), pi / 2.0))
            ret = false;
        }
      }
    }
    if (far(c, r) && far(c, l)) {
      REP(i, n) {
        line wl(wall[i], wall[NEXT(i, n)]);
        if (ccw(wl.first, wl.second, l) & OVER) {
          floatingArg = minArgs[1];  // right float
          nfloatingArg = minArgs[0]; // left touched
          break;
        }
        if (ccw(wl.first, wl.second, r) & OVER) {
          floatingArg = minArgs[0];  // left float
          nfloatingArg = minArgs[1]; // right touched
          break;
        }
      }
      if (leq(nfloatingArg, floatingArg)) {
        ret = false;
      }
    }
    c = nc;
    l = nl;
    r = nr;
    return ret;
  }
  void getCand(elem r, vector<point> &ret) {
    int n = wall.size();
    circle C(r, c);
    REP(i, n) {
      if (C.inCircle(wall[i])) {
        ret.push_back(wall[i]);
      }
      pp circle_is;
      int num =
          intersection_circle_seg(C, seg(wall[i], wall[NEXT(i, n)]), circle_is);
      if (num >= 1)
        ret.push_back(circle_is.first);
      if (num >= 2)
        ret.push_back(circle_is.second);
    }
  }
};

int main() {
  while (true) {
    elem L, R;
    int N;
    field F;

    scanf("%Lf%Lf%d", &L, &R, &N);
    if (L == 0 && R == 0 && N == 0)
      break;

    F.len = L;
    F.max_rot = 2 * pi * R;
    F.total_rot = 0;
    F.l = F.c = origin;
    F.r = point(0, L);

    for (int i = 0; i < N; ++i) {
      int x, y;
      scanf("%d%d", &x, &y);
      point p((elem)x, (elem)y);
      F.wall.push_back(p);
    }

    int seq = 0;
    while (!F.cannotRotateBar()) {
      if (!F.rotateBar(seq))
        break;
      ++seq;
    }
    printf("%.15Lf %.15Lf\\n", F.l.real(), F.l.imag());
  }
  return 0;
}