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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <vector>
using namespace std;

#define EPS 1e-10

typedef complex<double> P;

double cross(const P &a, const P &b) { return imag(conj(a) * b); }
double dot(const P &a, const P &b) { return real(conj(a) * b); }

struct L : public vector<P> {
  L(const P &a, const P &b) {
    push_back(a);
    push_back(b);
  }
};

int ccw(P a, P b, P c) {
  b -= a;
  c -= a;
  if (cross(b, c) > 0)
    return +1; // counter clockwise
  if (cross(b, c) < 0)
    return -1; // clockwise
  if (dot(b, c) < 0)
    return +2; // c--a--b on line
  if (norm(b) < norm(c))
    return -2; // a--b--c on line
  return 0;
}

bool intersectSS(const L &s, const L &t) {
  return ccw(s[0], s[1], t[0]) * ccw(s[0], s[1], t[1]) <= 0 &&
         ccw(t[0], t[1], s[0]) * ccw(t[0], t[1], s[1]) <= 0;
}

P crosspoint(const L &l, const L &m) {
  double A = cross(l[1] - l[0], m[1] - m[0]);
  double B = cross(l[1] - l[0], l[1] - m[0]);
  if (abs(A) < EPS && abs(B) < EPS)
    return m[0]; // same line
  if (abs(A) < EPS)
    assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m[0] + B / A * (m[1] - m[0]);
}

double dist2(P &a, P &b) {
  return (a.real() - b.real()) * (a.real() - b.real()) +
         (a.imag() - b.imag()) * (a.imag() - b.imag());
}

class XP {
public:
  int cg;
  double dist;
  XP(int cg, double dist) : cg(cg), dist(dist) {}

  bool operator<(const XP &a) const { return dist < a.dist; }
};

int main() {
  int N, M;
  scanf("%d", &N);
  while (N--) {
    int xa, ya, xb, yb;
    scanf("%d%d%d%d", &xa, &ya, &xb, &yb);
    L line = L(P(xa, ya), P(xb, yb));

    scanf("%d", &M);
    vector<XP> xp;
    while (M--) {
      int xs, ys, xt, yt, o, l;
      scanf("%d%d%d%d%d%d", &xs, &ys, &xt, &yt, &o, &l);
      L road = L(P(xs, ys), P(xt, yt));

      if (intersectSS(line, road)) {
        int cg = (o == l ? 1 : 0);
        P p = crosspoint(line, road);
        xp.push_back(XP(cg, dist2(line[0], p)));
      }
    }

    int cnt = 0;
    sort(xp.begin(), xp.end());
    if (xp.size() > 0) {
      int ps = xp[0].cg;
      for (int i = 1; i < xp.size(); i++) {
        if (xp[i].cg != ps) {
          cnt++;
          ps = xp[i].cg;
        }
      }
    }
    printf("%d\\n", cnt);
  }
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <vector>
using namespace std;

#define EPS 1e-10

typedef complex<double> P;

double cross(const P &a, const P &b) { return imag(conj(a) * b); }
double dot(const P &a, const P &b) { return real(conj(a) * b); }

struct L : public vector<P> {
  L(const P &a, const P &b) {
    push_back(a);
    push_back(b);
  }
};

int ccw(P a, P b, P c) {
  b -= a;
  c -= a;
  if (cross(b, c) > 0)
    return +1; // counter clockwise
  if (cross(b, c) < 0)
    return -1; // clockwise
  if (dot(b, c) < 0)
    return +2; // c--a--b on line
  if (norm(b) < norm(c))
    return -2; // a--b--c on line
  return 0;
}

bool intersectSS(const L &s, const L &t) {
  return ccw(s[0], s[1], t[0]) * ccw(s[0], s[1], t[1]) <= 0 &&
         ccw(t[0], t[1], s[0]) * ccw(t[0], t[1], s[1]) <= 0;
}

P crosspoint(const L &l, const L &m) {
  double A = cross(l[1] - l[0], m[1] - m[0]);
  double B = cross(l[1] - l[0], l[1] - m[0]);
  if (abs(A) < EPS && abs(B) < EPS)
    return m[0]; // same line
  if (abs(A) < EPS)
    assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m[0] + B / A * (m[1] - m[0]);
}

double dist2(P &a, P &b) {
  return (a.real() - b.real()) * (a.real() - b.real()) +
         (a.imag() - b.imag()) * (a.imag() - b.imag());
}

class XP {
public:
  int cg;
  double dist;
  XP(int cg, double dist) : cg(cg), dist(dist) {}

  bool operator<(const XP &a) const { return dist < a.dist; }
};

int main() {
  int N, M;
  scanf("%d", &N);
  while (N--) {
    int xa, ya, xb, yb;
    scanf("%d%d%d%d", &xa, &ya, &xb, &yb);
    L line = L(P(xa, ya), P(xb, yb));

    scanf("%d", &M);
    vector<XP> xp;
    while (M--) {
      int xs, ys, xt, yt, o, l;
      scanf("%d%d%d%d%d%d", &xs, &ys, &xt, &yt, &o, &l);
      L road = L(P(xs, ys), P(xt, yt));

      if (intersectSS(line, road)) {
        int cg = (o == l ? 1 : 0);
        P p = crosspoint(line, road);
        xp.push_back(XP(cg, dist2(line[0], p)));
      }
    }

    int cnt = 0;
    sort(xp.begin(), xp.end());
    int ps = xp[0].cg;
    for (int i = 1; i < xp.size(); i++) {
      if (xp[i].cg != ps) {
        cnt++;
        ps = xp[i].cg;
      }
    }

    printf("%d\\n", cnt);
  }
}