Problem p01285 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <bits/stdc++.h>
using namespace std;

#define dump(n) cout << "# " << #n << '=' << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define all(c) begin(c), end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

const int INF = 1e9;
const int MOD = 1e9 + 7;
// const double EPS=1e-9;
const double EPS = 1e-10;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << '(' << p.first << ',' << p.second << ')';
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &a) {
  os << '[';
  rep(i, a.size()) os << (i ? " " : "") << a[i];
  return os << ']';
}

struct Point {
  double x, y;
  Point() {}
  Point(double x, double y) : x(x), y(y) {}
  Point &operator+=(Point p) {
    x += p.x, y += p.y;
    return *this;
  }
  Point &operator-=(Point p) {
    x -= p.x, y -= p.y;
    return *this;
  }
  Point &operator*=(double c) {
    x *= c, y *= c;
    return *this;
  }
  Point &operator/=(double c) {
    x /= c, y /= c;
    return *this;
  }
};
Point operator+(Point a, Point b) { return a += b; }
Point operator-(Point a, Point b) { return a -= b; }
Point operator*(Point a, double c) { return a *= c; }
Point operator*(double c, Point a) { return a *= c; }
Point operator/(Point a, double c) { return a /= c; }
bool operator==(Point a, Point b) {
  return abs(a.x - b.x) < EPS && abs(a.y - b.y) < EPS;
}
bool operator!=(Point a, Point b) { return !(a == b); }

double Abs(Point p) { return sqrt(p.x * p.x + p.y * p.y); }
double Abs2(Point p) { return p.x * p.x + p.y * p.y; }
double Arg(Point p) { return atan2(p.y, p.x); }
double Dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }
double Cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }
Point Rot(Point p, double t) {
  return Point(cos(t) * p.x - sin(t) * p.y, sin(t) * p.x + cos(t) * p.y);
}

struct Line {
  Point pos, dir;
  Line() {}
  Line(Point p, Point d) : pos(p), dir(d) {}
  Line(double x, double y, double u, double v) : pos(x, y), dir(u, v) {}
};

Point Proj(Line l, Point p) {
  Point a = p - l.pos, b = l.dir;
  return l.pos + Dot(a, b) / Abs2(b) * b;
}

double DistLP(Line l, Point p) { return Abs(Proj(l, p) - p); }

Point InterPointLL(Line a, Line b) {
  if (abs(Cross(a.dir, b.dir)) < EPS)
    return a.pos;
  return a.pos + Cross(b.pos - a.pos, b.dir) / Cross(a.dir, b.dir) * a.dir;
}

bool Parallel(Line a, Line b) { return abs(Cross(a.dir, b.dir)) < EPS; }

vector<Line> EquidistantLine(Line a, Line b) {
  if (Parallel(a, b))
    return {Line((a.pos + b.pos) / 2, a.dir)};
  Point p = InterPointLL(a, b);
  a.dir /= Abs(a.dir), b.dir /= Abs(b.dir);
  return {Line(p, (a.dir + b.dir) / 2), Line(p, (a.dir - b.dir) / 2)};
}

ostream &operator<<(ostream &os, const Point &p) {
  return os << '(' << p.x << ',' << p.y << ')';
}

string solve(vector<Line> ls) {
  int n = ls.size();
  if (n <= 2)
    return "Many"; // trivial case

  Line a = ls[0], b = ls[1], c = ls[2];
  if (Parallel(a, b) && Parallel(b, c))
    return "None";

  // 平行な直線があるなら，aとbがそうであるようにする
  if (Parallel(a, c))
    swap(b, c);
  if (Parallel(b, c))
    swap(a, c);

  vector<Point> ps;
  if (Parallel(a, b)) {
    Line l = EquidistantLine(a, b)[0];
    auto els = EquidistantLine(a, c);
    ps.push_back(InterPointLL(l, els[0]));
    ps.push_back(InterPointLL(l, els[1]));
  } else {
    for (auto l1 : EquidistantLine(a, b))
      for (auto l2 : EquidistantLine(a, c))
        ps.push_back(InterPointLL(l1, l2));
  }
  sort(all(ps), [](Point a, Point b) {
    return abs(a.x - b.x) > EPS ? a.x < b.x : a.y < b.y;
  });
  ps.erase(unique(all(ps)), end(ps));

  vector<Point> qs;
  for (auto p : ps) {
    bool ok = true;
    rep(i, ls.size()) ok &= abs(DistLP(ls[i], p) - DistLP(ls[0], p)) < EPS;
    if (ok)
      qs.push_back(p);
  }

  if (qs.size() == 0)
    return "None";
  if (qs.size() >= 2)
    return "Many";
  return to_string(qs[0].x) + " " + to_string(qs[0].y);
}

int main() {
  for (int n; cin >> n && n;) {
    vector<Line> ls(n);
    rep(i, n) {
      int x1, y1, x2, y2;
      cin >> x1 >> y1 >> x2 >> y2;
      ls[i] = Line(x1, y1, x2 - x1, y2 - y1);
    }
    cout << solve(ls) << endl;
  }
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define dump(n) cout << "# " << #n << '=' << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define all(c) begin(c), end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

const int INF = 1e9;
const int MOD = 1e9 + 7;
const double EPS = 1e-9;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << '(' << p.first << ',' << p.second << ')';
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &a) {
  os << '[';
  rep(i, a.size()) os << (i ? " " : "") << a[i];
  return os << ']';
}

int Signum(double x) { return x < -EPS ? -1 : x > EPS ? 1 : 0; }

struct Point {
  double x, y;
  Point() {}
  Point(double x, double y) : x(x), y(y) {}
  Point &operator+=(Point p) {
    x += p.x, y += p.y;
    return *this;
  }
  Point &operator-=(Point p) {
    x -= p.x, y -= p.y;
    return *this;
  }
  Point &operator*=(double c) {
    x *= c, y *= c;
    return *this;
  }
  Point &operator/=(double c) {
    x /= c, y /= c;
    return *this;
  }
};
Point operator+(Point a, Point b) { return a += b; }
Point operator-(Point a, Point b) { return a -= b; }
Point operator*(Point a, double c) { return a *= c; }
Point operator*(double c, Point a) { return a *= c; }
Point operator/(Point a, double c) { return a /= c; }
bool operator==(Point a, Point b) {
  return abs(a.x - b.x) < EPS && abs(a.y - b.y) < EPS;
}
bool operator!=(Point a, Point b) { return !(a == b); }

double Abs(Point p) { return sqrt(p.x * p.x + p.y * p.y); }
double Abs2(Point p) { return p.x * p.x + p.y * p.y; }
double Arg(Point p) { return atan2(p.y, p.x); }
double Dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }
double Cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }
Point Rot(Point p, double t) {
  return Point(cos(t) * p.x - sin(t) * p.y, sin(t) * p.x + cos(t) * p.y);
}

struct Line {
  Point pos, dir;
  Line() {}
  Line(Point p, Point d) : pos(p), dir(d) {}
  Line(double x, double y, double u, double v) : pos(x, y), dir(u, v) {}
};

int CCW(Point a, Point b, Point c) {
  b -= a, c -= a;
  if (int sign = Signum(Cross(b, c)))
    return sign; // 1:ccw,-1:cw
  if (Dot(b, c) < -EPS)
    return -2; // c-a-b
  if (Abs2(b) < Abs2(c) - EPS)
    return 2; // a-b-c
  return 0;   // a-c-b (inclusive)
}

bool IntersectLL(Line a, Line b) {
  return abs(Cross(a.dir, b.dir)) > EPS ||
         abs(Cross(a.dir, b.pos - a.pos)) < EPS;
}
bool IntersectLP(Line l, Point p) {
  return abs(CCW(l.pos, l.pos + l.dir, p)) != 1;
}
Point InterPointLL(Line a, Line b) {
  if (abs(Cross(a.dir, b.dir)) < EPS)
    return a.pos;
  return a.pos + Cross(b.pos - a.pos, b.dir) / Cross(a.dir, b.dir) * a.dir;
}

ostream &operator<<(ostream &os, const Point &p) {
  return os << '(' << p.x << ',' << p.y << ')';
}
ostream &operator<<(ostream &os, const Line &l) {
  return os << '(' << l.pos << ',' << l.dir << ')';
}

string solve(vector<Line> ls) {
  int n = ls.size();
  if (n <= 2)
    return "Many"; // trivial case

  vector<vector<Line>> els; // equidistant lines
  rep(i, n) repi(j, i + 1, n) {
    Line a = ls[i], b = ls[j];
    if (IntersectLL(a, b)) {
      // "The lines do not coincide each other."なので直線は1点で交わる
      Point p = InterPointLL(a, b);
      a.dir /= Abs(a.dir), b.dir /= Abs(b.dir);
      els.push_back(
          {Line(p, (a.dir + b.dir) / 2), Line(p, (a.dir - b.dir) / 2)});
    } else {
      els.push_back({Line((a.pos + b.pos) / 2, a.dir)});
    }
  }

  // 全直線が平行
  if (all_of(all(els), [](const vector<Line> &a) { return a.size() == 1; })) {
    repi(i, 1,
         els.size()) if (!IntersectLL(els[0][0], els[i][0])) return "None";
    return "Many";
  }

  vector<Point> ps;
  rep(i, els.size())
      repi(j, i + 1, els.size()) for (Line a : els[i]) for (Line b : els[j]) {
    if (abs(Cross(a.dir, b.dir)) > EPS)
      ps.push_back(InterPointLL(a, b));
  }
  sort(all(ps), [](Point a, Point b) {
    return abs(a.x - b.x) > EPS ? a.x < b.x : a.y < b.y;
  });
  ps.erase(unique(all(ps)), end(ps));

  vector<Point> res;
  for (Point p : ps) {
    bool on = true;
    rep(i, els.size()) {
      bool tmp = false;
      for (Line l : els[i])
        tmp |= IntersectLP(l, p);
      if (!tmp) {
        on = false;
        break;
      }
    }
    if (on)
      res.push_back(p);
  }

  if (res.size() == 0)
    return "None";
  if (res.size() >= 2)
    return "Many";

  char tmp[100];
  sprintf(tmp, "%f %f", res[0].x, res[0].y);
  return tmp;
}

int main() {
  for (int n; cin >> n && n;) {
    vector<Line> ls(n);
    rep(i, n) {
      int x1, y1, x2, y2;
      cin >> x1 >> y1 >> x2 >> y2;
      ls[i] = Line(x1, y1, x2 - x1, y2 - y1);
    }
    cout << solve(ls) << endl;
  }
}