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

#include <algorithm>
#include <complex>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

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

const double eps = 1e-10;
const double pi = 3.14159265358979323846;

typedef double Num;
typedef complex<Num> Pt2;
typedef vector<Pt2> Polygon2;

struct Line2 : vector<Pt2> {
  Line2(Pt2 a, Pt2 b) {
    push_back(a);
    push_back(b);
  }
  Pt2 vec() { return (*this)[1] - (*this)[0]; }
};

Pt2 unit(Pt2 v) { return v / abs(v); }
Num dist(Pt2 a, Pt2 b) { return abs(a - b); }
Num dot(Pt2 a, Pt2 b) { return X(a * conj(b)); }
Num cross(Pt2 a, Pt2 b) { return Y(conj(a) * b); }
bool equal(Num a, Num b) { return abs(a - b) < eps; }
bool equal(Pt2 a, Pt2 b) { return equal(X(a), X(b)) && equal(Y(a), Y(b)); }

bool intersectLS(Line2 s, Line2 t) {
  return cross(s.vec(), t[0] - s[0]) * cross(s.vec(), t[1] - s[0]) < eps;
}

int main() {
  int H, W, px = -1, py = -1, pd = -1;
  char e[602][602] = {0};
  bool b[602][602] = {0};

  cin >> H >> W;
  for (int y = 1; y <= H; y++)
    for (int x = 1; x <= W; x++) {
      char c;
      cin >> c;
      if (c == '#') {
        b[y][x] = 1;
        if (px == -1) {
          px = x;
          py = y;
        }
      }
    }

  for (int y = 1; y <= H + 1; y++)
    for (int x = 1; x <= W + 1; x++) {
      if (b[y][x] != b[y - 1][x])
        e[y][x] |= 1;
      if (b[y][x] != b[y][x - 1])
        e[y][x] |= 2;
    }

  Polygon2 g;
  while (true) {
    int d = -1;
    if (e[py][px] & 1) {
      d = 0;
      e[py][px] -= 1;
    } else if (e[py][px] & 2) {
      d = 1;
      e[py][px] -= 2;
    } else if (e[py][px - 1] & 1) {
      d = 2;
      e[py][px - 1] -= 1;
    } else if (e[py - 1][px] & 2) {
      d = 3;
      e[py - 1][px] -= 2;
    }

    if (d == -1)
      break;
    if (d != pd)
      g.push_back(Pt2(px - 1, H + 1 - py));

    const int dx[] = {+1, 0, -1, 0};
    const int dy[] = {0, +1, 0, -1};
    px += dx[d];
    py += dy[d];
    pd = d;
  }

  vector<Num> ang;
  map<Num, int> vtx;
  for (int i = 0; i < g.size(); i++) {
    Num a = arg(g[i]), b = arg(g[(i + 1) % g.size()]);
    ang.push_back(a);

    if (equal(a, b))
      continue;
    if (a > b)
      swap(a, b);

    if (!vtx.insert(make_pair(a, 1)).second)
      vtx[a]++;
    if (!vtx.insert(make_pair(b, -1)).second)
      vtx[b]--;
  }

  sort(ang.begin(), ang.end());
  ang.erase(unique(ang.begin(), ang.end()), ang.end());

  int ans = 0, cnt = 0, idx = 1;
  map<Num, int>::iterator it;
  for (it = vtx.begin(); it != vtx.end(); it++) {
    while ((ang[idx - 1] + ang[idx]) / 2.0 < it->first && idx < ang.size()) {
      ans = max(ans, cnt);
      idx++;
    }
    if (idx >= ang.size())
      break;

    cnt += it->second;
  }

  cout << 1 + ans / 2 << endl;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <complex>
#include <iostream>
#include <vector>
using namespace std;

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

const double eps = 1e-10;
const double pi = 3.14159265358979323846;

typedef double Num;
typedef complex<Num> Pt2;
typedef vector<Pt2> Polygon2;

struct Line2 : vector<Pt2> {
  Line2(Pt2 a, Pt2 b) {
    push_back(a);
    push_back(b);
  }
  Pt2 vec() { return (*this)[1] - (*this)[0]; }
};

Pt2 unit(Pt2 v) { return v / abs(v); }
Num dist(Pt2 a, Pt2 b) { return abs(a - b); }
Num dot(Pt2 a, Pt2 b) { return X(a * conj(b)); }
Num cross(Pt2 a, Pt2 b) { return Y(conj(a) * b); }
bool equal(Num a, Num b) { return abs(a - b) < eps; }
bool equal(Pt2 a, Pt2 b) { return equal(X(a), X(b)) && equal(Y(a), Y(b)); }

bool intersectLS(Line2 s, Line2 t) {
  return cross(s.vec(), t[0] - s[0]) * cross(s.vec(), t[1] - s[0]) < eps;
}

int main() {
  int H, W;
  char e[602][602] = {0};
  bool b[602][602] = {0};

  cin >> H >> W;
  for (int y = 1; y <= H; y++)
    for (int x = 1; x <= W; x++) {
      char c;
      cin >> c;
      b[y][x] = (c == '#');
    }

  for (int y = 1; y <= H + 1; y++)
    for (int x = 1; x <= W + 1; x++) {
      if (b[y][x] != b[y - 1][x])
        e[y][x] |= 1;
      if (b[y][x] != b[y][x - 1])
        e[y][x] |= 2;
    }

  int px = -1, py = -1, pd = -1;
  for (int y = 1; y <= H; y++) {
    for (int x = 1; x <= W; x++) {
      if (b[y][x]) {
        px = x;
        py = y;
        break;
      }
    }
    if (px != -1)
      break;
  }

  Polygon2 g;
  while (true) {
    int d = -1;
    if (e[py][px] & 1) {
      d = 0;
      e[py][px] -= 1;
    } else if (e[py][px] & 2) {
      d = 1;
      e[py][px] -= 2;
    } else if (e[py][px - 1] & 1) {
      d = 2;
      e[py][px - 1] -= 1;
    } else if (e[py - 1][px] & 2) {
      d = 3;
      e[py - 1][px] -= 2;
    }

    if (d == -1)
      break;
    if (d != pd) {
      g.push_back(Pt2(px - 1, H + 1 - py));
    }

    const int dx[] = {+1, 0, -1, 0};
    const int dy[] = {0, +1, 0, -1};
    px += dx[d];
    py += dy[d];
    pd = d;
  }

  vector<Num> ang;
  for (int i = 0; i < g.size(); i++) {
    if (equal(g[0], Pt2(0, 0)))
      continue;
    ang.push_back(arg(g[i]));
  }
  sort(ang.begin(), ang.end());
  ang.erase(unique(ang.begin(), ang.end()), ang.end());

  int cnt_max = 0;
  for (int k = 0; k < ang.size() - 1; k++) {
    int cnt = 0;
    Line2 s(Pt2(0, 0), polar(1.0, (ang[k] + ang[k + 1]) / 2.0));
    for (int i = 0; i < g.size(); i++) {
      if (intersectLS(s, Line2(g[i], g[(i + 1) % g.size()])))
        cnt++;
    }
    cnt_max = max(cnt_max, cnt);
  }

  cout << (cnt_max / 2) + 1 << endl;
}

/*
3 3
a #.#
a ###
a #.#
*/