Problem p01708 (C++) — buggy submission, verdict: Runtime Error

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

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a) begin((a)), end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

#define FF first
#define SS second
template <class S, class T> istream &operator>>(istream &is, pair<S, T> &p) {
  return is >> p.FF >> p.SS;
}
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &p) {
  return os << p.FF << " " << p.SS;
}
template <class T> void maxi(T &x, T y) {
  if (x < y)
    x = y;
}
template <class T> void mini(T &x, T y) {
  if (x > y)
    x = y;
}

const double EPS = 1e-10;
const double PI = acos(-1.0);
const LL MOD = 1e9 + 7;

class Point {
public:
  double x, y;

  Point(double x = 0.0, double y = 0.0) : x(x), y(y) {}

  Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
  Point &operator+=(const Point &p) {
    x += p.x;
    y += p.y;
    return *this;
  }
  Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
  Point &operator-=(const Point &p) {
    x -= p.x;
    y -= p.y;
    return *this;
  }
  Point operator*(double a) const { return Point(a * x, a * y); }
  Point &operator*=(double a) {
    x *= a;
    y *= a;
    return *this;
  }
  Point operator/(double a) const { return Point(x / a, y / a); }
  Point &operator/=(double a) {
    x /= a;
    y /= a;
    return *this;
  }

  double abs() { return sqrt(norm()); }
  double norm() { return x * x + y * y; }

  bool operator<(const Point &p) const { return x != p.x ? x < p.x : y < p.y; }

  bool operator==(const Point &p) const {
    return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
  }
  friend ostream &operator<<(ostream &os, const Point &p);
};
ostream &operator<<(ostream &os, const Point &p) {
  return os << "(" << p.x << "," << p.y << ")";
}

class Segment {
public:
  Point p1, p2;
  Segment() {}
  Segment(const Point &p1_, const Point &p2_) : p1(p1_), p2(p2_) {}
};
typedef vector<Point> Polygon;
typedef Point Vector;
typedef Segment Line;
double dot(Vector a, Vector b) { return a.x * b.x + a.y * b.y; }
double cross(Vector a, Vector b) { return a.x * b.y - a.y * b.x; }
Point project(Line s, Point p) {
  Vector base = s.p2 - s.p1;
  double r = dot(p - s.p1, base) / base.norm();
  return s.p1 + base * r;
}
Point reflect(Segment s, Point p) { return p + (project(s, p) - p) * 2.0; }
Point getCrossPoint(Segment s1, Segment s2) {
  Vector a = s1.p2 - s1.p1;
  Vector b = s2.p2 - s2.p1;
  double t = cross(b, s2.p1 - s1.p1) / cross(b, a);
  Vector v = a * t;
  return s1.p1 + v;
}

struct P {
  int type;
  Point p1;
  Point p2;
  P() : type(-1) {}
};
int pos(int l, string &s, P &p) {
  int i, m = l + 1;
  p.type = 0;
  for (i = l + 1;; ++i) {
    if (s[i] == ',') {
      p.p1.x = stoi(s.substr(m, i - m));
      m = i + 1;
    } else if (s[i] == '}') {
      p.p1.y = stoi(s.substr(m, i - m));
      break;
    }
  }
  return i;
}
P op(P p1, P p2) {
  if (p1.type < 0)
    return p2;
  P res;
  if (p1.type == 0) {
    if (p2.type == 0) {
      res.type = 1;
      res.p1 = p1.p1;
      res.p2 = p2.p1;
    } else {
      res.type = 0;
      res.p1 = reflect(Segment(p2.p1, p2.p2), p1.p1);
    }
  } else {
    if (p2.type == 0) {
      res.type = 0;
      res.p1 = reflect(Segment(p1.p1, p1.p2), p2.p1);
    } else {
      res.type = 0;
      res.p1 = getCrossPoint(Segment(p1.p1, p1.p2), Segment(p2.p1, p2.p2));
    }
  }
  return res;
}
int find(int l, string &s) {
  int lv = 0;
  for (int i = l;; ++i) {
    if (s[i] == '(')
      ++lv;
    else if (s[i] == ')') {
      --lv;
      if (lv == 0) {
        return i;
      }
    }
  }
  return -1;
}

P parse(int l, int r, string &s) {
  P res;
  for (int i = l; i < r; ++i) {
    if (s[i] == '(') {
      int rr = find(i, s);
      res = parse(i + 1, rr, s);
      i = rr;
    } else if (s[i] == '@') {
      ++i;
      if (s[i] == '(') {
        int rr = find(i, s);
        res = op(res, parse(i + 1, rr, s));
        i = rr;
      } else if (s[i] == '{') {
        P tmp;
        i = pos(i, s, tmp);
        res = op(res, tmp);
      } else
        exit(1);
    } else if (s[i] == '{') {
      P tmp;
      i = pos(i, s, tmp);
      res = op(res, tmp);
    } else
      exit(1);
  }
  return res;
}

int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  string s;
  while (getline(cin, s)) {
    if (s == "#")
      break;
    REP(i, SZ(s)) {
      if (s[i] == '(' && (s[i + 1] == '-' || isdigit(s[i + 1])))
        s[i] = '{';
      else if (s[i] == ')' && (s[i - 1] == '-' || isdigit(s[i - 1])))
        s[i] = '}';
    }
    P ans = parse(0, SZ(s), s);
    cout << fixed << setprecision(9) << ans.p1.x << " " << ans.p1.y << endl;
  }

  return 0;
}

Error: WA

Fixed submission:

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

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a) begin((a)), end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

#define FF first
#define SS second
template <class S, class T> istream &operator>>(istream &is, pair<S, T> &p) {
  return is >> p.FF >> p.SS;
}
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &p) {
  return os << p.FF << " " << p.SS;
}
template <class T> void maxi(T &x, T y) {
  if (x < y)
    x = y;
}
template <class T> void mini(T &x, T y) {
  if (x > y)
    x = y;
}

const double EPS = 1e-10;
const double PI = acos(-1.0);
const LL MOD = 1e9 + 7;

class Point {
public:
  double x, y;

  Point(double x = 0.0, double y = 0.0) : x(x), y(y) {}

  Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
  Point &operator+=(const Point &p) {
    x += p.x;
    y += p.y;
    return *this;
  }
  Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
  Point &operator-=(const Point &p) {
    x -= p.x;
    y -= p.y;
    return *this;
  }
  Point operator*(double a) const { return Point(a * x, a * y); }
  Point &operator*=(double a) {
    x *= a;
    y *= a;
    return *this;
  }
  Point operator/(double a) const { return Point(x / a, y / a); }
  Point &operator/=(double a) {
    x /= a;
    y /= a;
    return *this;
  }

  double abs() { return sqrt(norm()); }
  double norm() { return x * x + y * y; }

  bool operator<(const Point &p) const { return x != p.x ? x < p.x : y < p.y; }

  bool operator==(const Point &p) const {
    return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
  }
  friend ostream &operator<<(ostream &os, const Point &p);
};
ostream &operator<<(ostream &os, const Point &p) {
  return os << "(" << p.x << "," << p.y << ")";
}

class Segment {
public:
  Point p1, p2;
  Segment() {}
  Segment(const Point &p1_, const Point &p2_) : p1(p1_), p2(p2_) {}
};
typedef vector<Point> Polygon;
typedef Point Vector;
typedef Segment Line;
double dot(Vector a, Vector b) { return a.x * b.x + a.y * b.y; }
double cross(Vector a, Vector b) { return a.x * b.y - a.y * b.x; }
Point project(Line s, Point p) {
  Vector base = s.p2 - s.p1;
  double r = dot(p - s.p1, base) / base.norm();
  return s.p1 + base * r;
}
Point reflect(Segment s, Point p) { return p + (project(s, p) - p) * 2.0; }
Point getCrossPoint(Segment s1, Segment s2) {
  Vector a = s1.p2 - s1.p1;
  Vector b = s2.p2 - s2.p1;
  double t = cross(b, s2.p1 - s1.p1) / cross(b, a);
  Vector v = a * t;
  return s1.p1 + v;
}

struct P {
  int type;
  Point p1;
  Point p2;
  P() : type(-1) {}
};
int pos(int l, string &s, P &p) {
  int i, m = l + 1;
  p.type = 0;
  for (i = l + 1;; ++i) {
    if (s[i] == ',') {
      p.p1.x = stoi(s.substr(m, i - m));
      m = i + 1;
    } else if (s[i] == '}') {
      p.p1.y = stoi(s.substr(m, i - m));
      break;
    }
  }
  return i;
}
P op(P p1, P p2) {
  if (p1.type < 0)
    return p2;
  P res;
  if (p1.type == 0) {
    if (p2.type == 0) {
      res.type = 1;
      res.p1 = p1.p1;
      res.p2 = p2.p1;
    } else {
      res.type = 0;
      res.p1 = reflect(Segment(p2.p1, p2.p2), p1.p1);
    }
  } else {
    if (p2.type == 0) {
      res.type = 0;
      res.p1 = reflect(Segment(p1.p1, p1.p2), p2.p1);
    } else {
      res.type = 0;
      res.p1 = getCrossPoint(Segment(p1.p1, p1.p2), Segment(p2.p1, p2.p2));
    }
  }
  return res;
}
int find(int l, string &s) {
  int lv = 0;
  for (int i = l;; ++i) {
    if (s[i] == '(')
      ++lv;
    else if (s[i] == ')') {
      --lv;
      if (lv == 0) {
        return i;
      }
    }
  }
  return -1;
}

P parse(int l, int r, string &s) {
  P res;
  for (int i = l; i < r; ++i) {
    if (s[i] == '(') {
      int rr = find(i, s);
      res = parse(i + 1, rr, s);
      i = rr;
    } else if (s[i] == '@') {
      ++i;
      if (s[i] == '(') {
        int rr = find(i, s);
        res = op(res, parse(i + 1, rr, s));
        i = rr;
      } else if (s[i] == '{') {
        P tmp;
        i = pos(i, s, tmp);
        res = op(res, tmp);
      } else
        exit(1);
    } else if (s[i] == '{') {
      P tmp;
      i = pos(i, s, tmp);
      res = op(res, tmp);
    } else
      exit(1);
  }
  return res;
}

int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  string s;
  while (getline(cin, s)) {
    if (s == "#")
      break;
    REP(i, SZ(s)) {
      if (s[i] == '(' && isdigit(s[i + 1]))
        s[i] = '{';
      else if (s[i] == ')' && isdigit(s[i - 1]))
        s[i] = '}';
    }
    P ans = parse(0, SZ(s), s);
    cout << fixed << setprecision(9) << ans.p1.x << " " << ans.p1.y << endl;
  }

  return 0;
}