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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cout << *i << " ";
  cout << endl;
}

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;

#include <complex>
#define CURR(P, i) (P[(i) % P.size()])
#define NEXT(P, i) (P[((i) + 1) % P.size()])

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

namespace std {
bool operator<(const Point &a, const Point &b) {
  return a.real() != b.real() ? a.real() < b.real() : a.imag() < b.imag();
}
} // namespace std

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

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

int ccw(Point a, Point b, Point c) {
  b -= a;
  c -= a;
  double len = abs(b) * abs(c);
  if (cross(b, c) > +EPS * len)
    return +1; // counter-clockwise
  if (cross(b, c) < -EPS * len)
    return -1; // clockwise
  if (dot(b, c) < 0)
    return +2; // c--a--b
  if (norm(b) < norm(c))
    return -2; // a--b--c
  return 0;    // a--c--b
}

enum { OUT, ON, IN };
int contains(const Circle &C, Point p) {
  p -= C.p;
  if (abs(C.r - abs(p)) < EPS)
    return ON;
  if (C.r > abs(p))
    return IN;
  if (C.r < abs(p))
    return OUT;
  assert(false);
}
// pをm中心にtだけ回転
Point rotate(Point p, Point m, double t) {
  p -= m;
  p = Point(p.real() * cos(t) - p.imag() * sin(t),
            p.real() * sin(t) + p.imag() * cos(t));
  return p + m;
}
Polygon rotate(Polygon P, Point m, double t) {
  REP(i, P.size()) { P[i] = rotate(P[i], m, t); }
  return P;
}
int main() {
  int N, R, Q;
  while (cin >> N >> R >> Q && N) {
    Polygon object;
    REP(i, N) {
      int x, y;
      cin >> x >> y;
      object.push_back(Point(x, y));
    }
    Circle sphere(Point(0, 0), (double)R);
    int touchindex = -1;
    REP(i, N) {
      if (contains(sphere, object[i]) == ON)
        touchindex = i;
    }
    assert(touchindex != -1);
    REP(iter, Q) {
      double lower = 0, upper = 2.0 * M_PI;
      REP(iter2, 40) {
        double mid = (lower + upper) / 2.0;
        Polygon rotated = rotate(object, object[touchindex], mid);
        bool pointisout = false;
        REP(i, N) {
          if (i == touchindex)
            continue;
          int judge = contains(sphere, rotated[i]);
          if (judge == OUT)
            pointisout = true;
        }
        if (pointisout) {
          upper = mid;
        } else {
          lower = mid;
        }
      }
      int newtouchindex = -1;
      Polygon newobject = rotate(object, object[touchindex], lower);
      REP(i, N) {
        if (i != touchindex && contains(sphere, newobject[i]) == ON) {
          if (newtouchindex == -1 ||
              abs(newobject[newtouchindex] - object[touchindex]) <
                  abs(newobject[i] - object[touchindex])) {
            newtouchindex = i;
          }
        }
      }
      assert(newtouchindex != -1);
      printf("%.12f %.12f\\n", newobject[newtouchindex].real(),
             newobject[newtouchindex].imag());
      object = newobject;
      touchindex = newtouchindex;
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cout << *i << " ";
  cout << endl;
}

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;

#include <complex>
#define CURR(P, i) (P[(i) % P.size()])
#define NEXT(P, i) (P[((i) + 1) % P.size()])

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

namespace std {
bool operator<(const Point &a, const Point &b) {
  return a.real() != b.real() ? a.real() < b.real() : a.imag() < b.imag();
}
} // namespace std

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

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

int ccw(Point a, Point b, Point c) {
  b -= a;
  c -= a;
  double len = abs(b) * abs(c);
  if (cross(b, c) > +EPS * len)
    return +1; // counter-clockwise
  if (cross(b, c) < -EPS * len)
    return -1; // clockwise
  if (dot(b, c) < 0)
    return +2; // c--a--b
  if (norm(b) < norm(c))
    return -2; // a--b--c
  return 0;    // a--c--b
}

enum { OUT, ON, IN };
int contains(const Circle &C, Point p) {
  p -= C.p;
  if (abs(C.r - abs(p)) < EPS)
    return ON;
  if (C.r > abs(p))
    return IN;
  if (C.r < abs(p))
    return OUT;
  assert(false);
}
// pをm中心にtだけ回転
Point rotate(Point p, Point m, double t) {
  p -= m;
  p = Point(p.real() * cos(t) - p.imag() * sin(t),
            p.real() * sin(t) + p.imag() * cos(t));
  return p + m;
}
Polygon rotate(Polygon P, Point m, double t) {
  REP(i, P.size()) { P[i] = rotate(P[i], m, t); }
  return P;
}
int main() {
  int N, R, Q;
  while (cin >> N >> R >> Q && N) {
    Polygon object;
    REP(i, N) {
      int x, y;
      cin >> x >> y;
      object.push_back(Point(x, y));
    }
    Circle sphere(Point(0, 0), (double)R);
    int touchindex = -1;
    REP(i, N) {
      if (contains(sphere, object[i]) == ON)
        touchindex = i;
    }
    assert(touchindex != -1);
    REP(iter, Q) {
      double lower = 0, upper = 2.0 * M_PI;
      REP(iter2, 60) {
        double mid = (lower + upper) / 2.0;
        Polygon rotated = rotate(object, object[touchindex], mid);
        bool pointisout = false;
        REP(i, N) {
          if (i == touchindex)
            continue;
          int judge = contains(sphere, rotated[i]);
          if (judge == OUT)
            pointisout = true;
        }
        if (pointisout) {
          upper = mid;
        } else {
          lower = mid;
        }
      }
      int newtouchindex = -1;
      Polygon newobject = rotate(object, object[touchindex], lower);
      REP(i, N) {
        if (i != touchindex && contains(sphere, newobject[i]) == ON) {
          if (newtouchindex == -1 ||
              abs(newobject[newtouchindex] - object[touchindex]) <
                  abs(newobject[i] - object[touchindex])) {
            newtouchindex = i;
          }
        }
      }
      assert(newtouchindex != -1);
      printf("%.12f %.12f\\n", newobject[newtouchindex].real(),
             newobject[newtouchindex].imag());
      object = newobject;
      touchindex = newtouchindex;
    }
  }
  return 0;
}