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

#include <bits/stdc++.h>

using namespace std;

#define uniq(xs) ((xs).erase(unique((xs).begin(), (xs).end()), (xs).end()))

namespace {

template <class T> ostream &operator<<(ostream &os, const vector<T> &vs) {
  if (vs.empty())
    return os << "[]";
  os << "[" << vs[0];
  for (int i = 1; i < vs.size(); i++)
    os << " " << vs[i];
  return os << "]";
}

const double EPS = 1e-5;

bool EQ(double x, double y) { return abs(x - y) < EPS; }

struct Point {
  double x, y;
  Point() {}
  Point(double x, double y) : x(x), y(y) {}
  Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
  Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
  Point operator*(double k) const { return Point(k * x, k * y); }
  Point operator/(double k) const { return Point(x / k, y / k); }
  bool operator==(const Point &p) const { return EQ(x, p.x) && EQ(y, p.y); }
  bool operator<(const Point &p) const {
    return EQ(x, p.x) ? y < p.y : x < p.x;
  }
};
double dot(const Point &a, const Point &b) { return a.x * b.x + a.y * b.y; }
double cross(const Point &a, const Point &b) { return a.x * b.y - a.y * b.x; }
double norm(const Point &a) { return sqrt(dot(a, a)); }
double angle(const Point &a) { return atan2(a.y, a.x); }
Point rot90(const Point &p) { return Point(-p.y, p.x); } // 反時計回りに90度回転
ostream &operator<<(ostream &os, const Point &p) {
  return os << "(" << p.x << "," << p.y << ")";
}
istream &operator>>(istream &is, Point &p) { return is >> p.x >> p.y; }

int H, W;
vector<string> F;
void input() {
  cin >> H >> W;
  F.clear();
  F.resize(H);
  for (int i = 0; i < H; i++) {
    cin >> F[i];
  }
}

struct E {
  Point p;
  bool type;
  E() {}
  E(Point p, bool type) : p(p), type(type) {}
  bool operator<(const E &e) const {
    double a = angle(p), b = angle(e.p);
    return (EQ(a, b) ? type > e.type : a > b);
  }
};
ostream &operator<<(ostream &os, const E &e) {
  return os << "E(" << e.p << "->" << e.type << ")";
}

void C(int y, int x, priority_queue<E> &Q) {
  string s, t;
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
      int ny = y - i, nx = x - j;
      if (ny < 0 || nx < 0) {
        s.push_back('.');
      } else {
        s.push_back(F[ny][nx]);
      }
      ny = y + i, nx = x + j;
      if (ny >= H || nx >= W) {
        t.push_back('.');
      } else {
        t.push_back(F[ny][nx]);
      }
    }
  }

  if (false) {
    cout << y << " " << x << endl;
    cout << s << " " << t << endl;
  }
  if (s == "#..." || s == "###.") {
    Point p(x, H - y);
    Q.push(E(p, s == "###."));
  }
  if (t == "#..." || t == "###.") {
    Point p(x + 1, H - (y + 1));
    Q.push(E(p, t == "#..."));
  }
}

void solve() {
  priority_queue<E> Q;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      C(i, j, Q);
    }
  }
  int ans = 1;
  int c = 1;
  while (!Q.empty()) {
    E e = Q.top();
    Q.pop();
    c += (e.type ? +1 : -1);
    ans = max(ans, c);
  }
  cout << ans << endl;
}
} // namespace

int main() {
  input();
  solve();
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define uniq(xs) ((xs).erase(unique((xs).begin(), (xs).end()), (xs).end()))

namespace {

template <class T> ostream &operator<<(ostream &os, const vector<T> &vs) {
  if (vs.empty())
    return os << "[]";
  os << "[" << vs[0];
  for (int i = 1; i < vs.size(); i++)
    os << " " << vs[i];
  return os << "]";
}

const double EPS = 1e-8;

bool EQ(double x, double y) { return abs(x - y) < EPS; }

struct Point {
  double x, y;
  Point() {}
  Point(double x, double y) : x(x), y(y) {}
  Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
  Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
  Point operator*(double k) const { return Point(k * x, k * y); }
  Point operator/(double k) const { return Point(x / k, y / k); }
  bool operator==(const Point &p) const { return EQ(x, p.x) && EQ(y, p.y); }
  bool operator<(const Point &p) const {
    return EQ(x, p.x) ? y < p.y : x < p.x;
  }
};
double dot(const Point &a, const Point &b) { return a.x * b.x + a.y * b.y; }
double cross(const Point &a, const Point &b) { return a.x * b.y - a.y * b.x; }
double norm(const Point &a) { return sqrt(dot(a, a)); }
Point rot90(const Point &p) { return Point(-p.y, p.x); } // 反時計回りに90度回転
ostream &operator<<(ostream &os, const Point &p) {
  return os << "(" << p.x << "," << p.y << ")";
}
istream &operator>>(istream &is, Point &p) { return is >> p.x >> p.y; }

int ccw(Point a, Point b, Point c) {
  b = b - a;
  c = c - a;
  if (cross(b, c) > EPS)
    return +1; // a,b,cの順に反時計周り
  if (cross(b, c) < -EPS)
    return -1; // a,b,cの順に時計周り
  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 直線
}

struct Segment {
  Point a, b;
  Segment() {}
  Segment(const Point &a, const Point &b) : a(a), b(b) {}
};
bool intersects(const Segment &s, const Segment &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;
}
ostream &operator<<(ostream &os, const Segment &s) {
  return os << "Segment(" << s.a << "," << s.b << ")";
}

Point crosspoint(const Segment &s, const Segment &t) {
  assert(intersects(s, t));
  double d = cross(t.b - t.a, s.b - s.a);
  assert(abs(d) >= EPS);
  return s.a + (s.b - s.a) * cross(t.b - t.a, t.b - s.a) / d;
}

int H, W;
vector<string> F;
void input() {
  cin >> H >> W;
  F.clear();
  F.resize(H);
  for (int i = 0; i < H; i++) {
    cin >> F[i];
  }
  reverse(F.begin(), F.end());
}

int count(const vector<Segment> &L, const Segment &s) {
  int ret = 0;
  for (int i = 0; i < L.size(); i++) {
    const Segment &t = L[i];
    if (intersects(s, t))
      ret++;
  }
  return ret;
}

const int dy[] = {1, 0}, dx[] = {0, 1};
void solve() {
  vector<Segment> L;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      int y = i, x = j;
      for (int k = 0; k < 2; k++) {
        int ny = y + dy[k], nx = x + dx[k];
        if (ny >= H || nx >= W) {
          if (F[y][x] == '#') {
            if (x == nx) {
              L.push_back(Segment(Point(nx, ny), Point(nx + 1, ny)));
            } else if (y == ny) {
              L.push_back(Segment(Point(nx, ny), Point(nx, ny + 1)));
            }
          }
          continue;
        }
        if ((F[y][x] == '#' && (ny >= H || nx >= W)) ||
            (F[ny][nx] != F[y][x])) {
          if (x == nx) {
            L.push_back(Segment(Point(nx, ny), Point(nx + 1, ny)));
          } else if (y == ny) {
            L.push_back(Segment(Point(nx, ny), Point(nx, ny + 1)));
          }
          continue;
        }
      }
    }
  }
  int ans = 0;
  for (int i = 0; i < H; i++) {
    double x = double(W);
    for (int k = 0; k < 10; k++) {
      double y = double(i) + k * 0.1 + 1.0 / 991;
      ans = max(ans, count(L, Segment(Point(0, 0), Point(x, y))));
    }
  }
  for (int j = 0; j < W; j++) {
    double y = double(H);
    for (int k = 0; k < 10; k++) {
      double x = double(j) + k * 0.1 + 1.0 / 991;
      ans = max(ans, count(L, Segment(Point(0, 0), Point(x, y))));
    }
  }
  cout << 1 + (ans + 1) / 2 << endl;
}
} // namespace

int main() {
  input();
  solve();
  return 0;
}