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

#include <algorithm>
#include <bitset>
#include <cctype>
#include <complex>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>

#define VARIABLE(x) cerr << #x << "=" << x << endl
#define BINARY(x) static_cast<bitset<16>>(x)
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define REP(i, m, n) for (int i = m; i < (int)(n); i++)
#define if_range(x, y, w, h)                                                   \\
  if (0 <= (int)(x) && (int)(x) < (int)(w) && 0 <= (int)(y) &&                 \\
      (int)(y) < (int)(h))
#define ALL(a) (a).begin(), (a).end()
const int INF = 1e9;
int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0};
using namespace std;
typedef long long ll;
// typedef pair<int, int> P;

/* struct P {
        int x, y, n;
        P(int n, int x, int y):n(n), x(x), y(y){}
        P(){}
}; */

/** 幾何ライブラリ **/
#include <complex>

#define X real()
#define Y imag()

const double EPS = 1e-8;
const double PI = acos(-1.0);

typedef double D;
typedef complex<D> P; // Point

struct L { // Line
  P a, b;
  L() {}
  L(P aa, P bb) : a(aa), b(bb) {}
};

// 共役複素数 conj(a);

// 符号
int sig(D a, D b = 0) {
  if (a < b - EPS)
    return -1;
  if (a > b + EPS)
    return 1;
  return 0;
}

// 内積
D dot(P a, P b) { return (conj(a) * b).real(); }

// 外積
D cross(P a, P b) { return (conj(a) * b).imag(); }

// 線分abに対する点cの位置
enum STATE {
  LEFT = 1,
  RIGHT = -1,
  BACK = 2,
  FRONT = -2,
  ON = 0,
  IN = 3,
  OUT = -3
};
int ccw(P a, P b, P c) {
  b -= a, c -= a;
  D s = sig(cross(b, c));
  if (s)
    return s > 0 ? LEFT : RIGHT;
  if (sig(dot(b, c)) < 0)
    return BACK;
  if (sig(abs(c), abs(b)) > 0)
    return FRONT;
  return ON;
}

// 直線lに対する点pの写像
P projection(L l, P p) {
  return l.a + (l.b - l.a) / abs(l.b - l.a) * dot(l.b - l.a, p - l.a) /
                   abs(l.b - l.a);
}

// 直線lに対する点pの反射
P reflection(L l, P p) { return p + (projection(l, p) - p) * P(2, 0); }

// 直線abと点cの距離
D dLP(L l, P c) { return abs(cross(l.b - l.a, c - l.a)) / abs(l.b - l.a); }

// 線分abと点cの距離
D dSP(L l, P c) {
  if (sig(dot(l.b - l.a, c - l.a)) < 0)
    return abs(c - l.a);
  if (sig(dot(l.a - l.b, c - l.b)) < 0)
    return abs(c - l.b);
  return abs(cross(l.b - l.a, c - l.a)) / abs(l.b - l.a);
}

// 線分と線分の交差判定
bool iSS(L s, L t) {
  return (ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0) &&
         (ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0);
}

// 線分と線分の距離
D dSS(L s, L t) {
  if (iSS(s, t))
    return 0;
  return min(min(dSP(t, s.a), dSP(t, s.b)), min(dSP(s, t.a), dSP(s, t.b)));
}

// 線分と線分の交点 (公差していることが前提)
P cSS(L s, L t) {
  D d1 = dLP(t, s.a);
  D d2 = dLP(t, s.b);
  D tmp = d1 / (d1 + d2);
  return s.a + (s.b - s.a) * tmp;
}

// 直線と直線の交差判定
bool iLL(L s, L t) { return sig(cross(s.b - s.a, t.b - t.a)) != 0; }

// 直線と直線の交点 iLLを確認してから使用
P cLL(L s, L t) {
  P ss = s.b - s.a, tt = t.b - t.a;
  return s.a + ss * cross(tt, t.a - s.a) / cross(tt, ss);
}

// 多角形
typedef vector<P> G;

// 面積を求める
D area(G g) {
  D res = 0.0;
  for (int i = 0; i < g.size(); i++) {
    res += cross(g[i], g[(i + 1) % g.size()]);
  }
  return abs(res) / 2;
}

// 多角形gと点pの包含関係を求める
int containsGP(G g, P p) {
  bool in = false;
  for (int i = 0; i < g.size(); i++) {
    P a = g[i], b = g[(i + 1) % g.size()];
    if (ccw(a, b, p) == ON)
      return ON;

    a -= p, b -= p;
    if (a.Y > b.Y)
      swap(a, b);
    if (a.Y < 0 && b.Y >= 0 && sig(cross(a, b)) > 0)
      in = !in;
  }
  return in ? IN : OUT;
}

bool cmp_convex_full(const P &a, const P &b) {
  if (sig(a.X, b.X) != 0)
    return a.X < b.X;
  return a.Y < b.Y;
}

// 凸包を得る
// 辺上を含めない場合は <= 0 にする
G convex_hull(vector<P> ps) {
  if (ps.size() == 1)
    return ps;

  int N = (int)ps.size(), k = 0;
  sort(ps.begin(), ps.end(), cmp_convex_full);
  G res(2 * N);

  for (int i = 0; i < N; i++) {
    while (k >= 2 && ccw(res[k - 2], res[k - 1], ps[i]) == RIGHT)
      k--;
    res[k++] = ps[i];
  }

  int t = k + 1;
  for (int i = N - 2; i >= 0; i--) {
    while (k >= t && ccw(res[k - 2], res[k - 1], ps[i]) == RIGHT)
      k--;
    res[k++] = ps[i];
  }
  res.resize(k - 1);
  return res;
}

// 凸多角形を直線で切断し、左側を残す
G convex_cut(G g, L l) {
  G res;
  for (int i = 0; i < g.size(); i++) {
    P a = g[i], b = g[(i + 1) % g.size()];
    if (ccw(l.a, l.b, a) != RIGHT)
      res.push_back(a);
    if (ccw(l.a, l.b, a) * ccw(l.a, l.b, b) < 0)
      res.push_back(cLL(L(a, b), l));
  }
  return res;
}

int main() {
  int N;
  while (cin >> N, N) {
    G g;
    rep(i, N) {
      D r, im;
      cin >> r >> im;
      g.push_back(P(r, im));
    }

    P t = P(1, 0);
    D SA = area(g) / 2, S1 = area(convex_cut(g, L(P(0, 0), t)));
    D la = 0, ua = PI;

    if (sig(S1, SA) > 0) {
      la = -PI, ua = 0;
    }

    rep(i, 1000) {
      D ma = (la + ua) / 2;

      t = P(cos(ma), sin(ma));

      S1 = area(convex_cut(g, L(P(0, 0), t)));

      if (sig(S1, SA) == 0) {
        //				cout << S1 << endl;
        //				cout << SA << endl;
        break;
      } else if (sig(S1, SA) < 0) {
        la = ma;
      } else {
        ua = ma;
      }
    }

    cout << fixed << setprecision(15);
    cout << t.X << " " << t.Y << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cctype>
#include <complex>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>

#define VARIABLE(x) cerr << #x << "=" << x << endl
#define BINARY(x) static_cast<bitset<16>>(x)
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define REP(i, m, n) for (int i = m; i < (int)(n); i++)
#define if_range(x, y, w, h)                                                   \\
  if (0 <= (int)(x) && (int)(x) < (int)(w) && 0 <= (int)(y) &&                 \\
      (int)(y) < (int)(h))
#define ALL(a) (a).begin(), (a).end()
const int INF = 1e9;
int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0};
using namespace std;
typedef long long ll;
// typedef pair<int, int> P;

/* struct P {
        int x, y, n;
        P(int n, int x, int y):n(n), x(x), y(y){}
        P(){}
}; */

/** 幾何ライブラリ **/
#include <complex>

#define X real()
#define Y imag()

const double EPS = 1e-8;
const double PI = acos(-1.0);

typedef double D;
typedef complex<D> P; // Point

struct L { // Line
  P a, b;
  L() {}
  L(P aa, P bb) : a(aa), b(bb) {}
};

// 共役複素数 conj(a);

// 符号
int sig(D a, D b = 0) {
  if (a < b - EPS)
    return -1;
  if (a > b + EPS)
    return 1;
  return 0;
}

// 内積
D dot(P a, P b) { return (conj(a) * b).real(); }

// 外積
D cross(P a, P b) { return (conj(a) * b).imag(); }

// 線分abに対する点cの位置
enum STATE {
  LEFT = 1,
  RIGHT = -1,
  BACK = 2,
  FRONT = -2,
  ON = 0,
  IN = 3,
  OUT = -3
};
int ccw(P a, P b, P c) {
  b -= a, c -= a;
  D s = sig(cross(b, c));
  if (s)
    return s > 0 ? LEFT : RIGHT;
  if (sig(dot(b, c)) < 0)
    return BACK;
  if (sig(abs(c), abs(b)) > 0)
    return FRONT;
  return ON;
}

// 直線lに対する点pの写像
P projection(L l, P p) {
  return l.a + (l.b - l.a) / abs(l.b - l.a) * dot(l.b - l.a, p - l.a) /
                   abs(l.b - l.a);
}

// 直線lに対する点pの反射
P reflection(L l, P p) { return p + (projection(l, p) - p) * P(2, 0); }

// 直線abと点cの距離
D dLP(L l, P c) { return abs(cross(l.b - l.a, c - l.a)) / abs(l.b - l.a); }

// 線分abと点cの距離
D dSP(L l, P c) {
  if (sig(dot(l.b - l.a, c - l.a)) < 0)
    return abs(c - l.a);
  if (sig(dot(l.a - l.b, c - l.b)) < 0)
    return abs(c - l.b);
  return abs(cross(l.b - l.a, c - l.a)) / abs(l.b - l.a);
}

// 線分と線分の交差判定
bool iSS(L s, L t) {
  return (ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0) &&
         (ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0);
}

// 線分と線分の距離
D dSS(L s, L t) {
  if (iSS(s, t))
    return 0;
  return min(min(dSP(t, s.a), dSP(t, s.b)), min(dSP(s, t.a), dSP(s, t.b)));
}

// 線分と線分の交点 (公差していることが前提)
P cSS(L s, L t) {
  D d1 = dLP(t, s.a);
  D d2 = dLP(t, s.b);
  D tmp = d1 / (d1 + d2);
  return s.a + (s.b - s.a) * tmp;
}

// 直線と直線の交差判定
bool iLL(L s, L t) { return sig(cross(s.b - s.a, t.b - t.a)) != 0; }

// 直線と直線の交点 iLLを確認してから使用
P cLL(L s, L t) {
  P ss = s.b - s.a, tt = t.b - t.a;
  return s.a + ss * cross(tt, t.a - s.a) / cross(tt, ss);
}

// 多角形
typedef vector<P> G;

// 面積を求める (時計回りだと負になる)
D area(G g) {
  D res = 0.0;
  for (int i = 0; i < g.size(); i++) {
    res += cross(g[i], g[(i + 1) % g.size()]);
  }
  return res / 2;
}

// 多角形gと点pの包含関係を求める
int containsGP(G g, P p) {
  bool in = false;
  for (int i = 0; i < g.size(); i++) {
    P a = g[i], b = g[(i + 1) % g.size()];
    if (ccw(a, b, p) == ON)
      return ON;

    a -= p, b -= p;
    if (a.Y > b.Y)
      swap(a, b);
    if (a.Y < 0 && b.Y >= 0 && sig(cross(a, b)) > 0)
      in = !in;
  }
  return in ? IN : OUT;
}

bool cmp_convex_full(const P &a, const P &b) {
  if (sig(a.X, b.X) != 0)
    return a.X < b.X;
  return a.Y < b.Y;
}

// 凸包を得る
// 辺上を含めない場合は <= 0 にする
G convex_hull(vector<P> ps) {
  if (ps.size() == 1)
    return ps;

  int N = (int)ps.size(), k = 0;
  sort(ps.begin(), ps.end(), cmp_convex_full);
  G res(2 * N);

  for (int i = 0; i < N; i++) {
    while (k >= 2 && ccw(res[k - 2], res[k - 1], ps[i]) == RIGHT)
      k--;
    res[k++] = ps[i];
  }

  int t = k + 1;
  for (int i = N - 2; i >= 0; i--) {
    while (k >= t && ccw(res[k - 2], res[k - 1], ps[i]) == RIGHT)
      k--;
    res[k++] = ps[i];
  }
  res.resize(k - 1);
  return res;
}

// 凸多角形を直線で切断し、左側を残す
G convex_cut(G g, L l) {
  G res;
  for (int i = 0; i < g.size(); i++) {
    P a = g[i], b = g[(i + 1) % g.size()];
    if (ccw(l.a, l.b, a) != RIGHT)
      res.push_back(a);
    if (ccw(l.a, l.b, a) * ccw(l.a, l.b, b) < 0)
      res.push_back(cLL(L(a, b), l));
  }
  return res;
}

int main() {
  int N;
  while (cin >> N, N) {
    G g;
    rep(i, N) {
      D r, im;
      cin >> r >> im;
      g.push_back(P(r, im));
    }

    P t = P(0, 1);
    D SA = area(g) / 2, S1 = area(convex_cut(g, L(P(0, 0), t)));
    D la = 0, ua = PI;

    if (sig(S1, SA) > 0) {
      ua = 0, la = PI;
    }

    while (true) {
      D ma = (la + ua) / 2;

      t = P(cos(ma), sin(ma));

      S1 = area(convex_cut(g, L(P(0, 0), t)));

      if (sig(S1, SA) == 0) {
        //				cout << S1 << endl;
        //				cout << SA << endl;
        break;
      } else if (sig(S1, SA) < 0) {
        la = ma;
      } else {
        ua = ma;
      }
    }

    cout << fixed << setprecision(15);
    cout << t.X << " " << t.Y << endl;
  }
}