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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;

using int64 = int64_t;

typedef complex<double> P;

struct Pid {
  P p;
  int id;

  Pid() {}
  Pid(P a, int b) : p(a), id(b) {}

  bool operator<(const Pid &o) const {
    return real(p) == real(o.p) ? imag(p) < imag(o.p) : real(p) < real(o.p);
  }
};

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

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

bool has_intersection(const P k1, const P k2, const P l1, const P l2) {
  return cross(l1 - k1, k2 - k1) * cross(l2 - k1, k2 - k1) < 0 &&
         cross(k1 - l1, l2 - l1) * cross(k2 - l1, l2 - l1) < 0;
}

P intersect(const P k1, const P k2, const P l1, const P l2) {
  assert(has_intersection(k1, k2, l1, l2));
  //  { ((l2-l1) . (k1-l1)) / abs(l2-l1)^2 } * (l2-l1) + l1
  double c1 = abs(cross(k2 - k1, l1 - k1)), c2 = abs(cross(k2 - k1, l2 - k1));
  return l1 + c1 / (c1 + c2) * (l2 - l1);
}

int xa, ya, xb, yb, N;
P s[100], t[100];
int o[100], l[100];

int solve() {
  P a(xa, ya), b(xb, yb);

  vector<Pid> its;
  for (int j = 0; j < N; ++j)
    if (has_intersection(a, b, s[j], t[j])) {
      its.emplace_back(intersect(a, b, s[j], t[j]), j);
    }

  sort(begin(its), end(its));

  int ans = 0;
  for (int j = 0; j < (int)its.size() - 1; ++j) {
    int v = o[its[j].id] == 1 ? l[its[j].id] : 1 - l[its[j].id];
    int w = o[its[j + 1].id] == 1 ? l[its[j + 1].id] : 1 - l[its[j + 1].id];
    if (v != w) {
      ++ans;
    }
  }
  return ans;
}

int main() {
  int datasets;
  cin >> datasets;
  for (int d = 0; d < datasets; ++d) {
    cin >> xa >> ya >> xb >> yb >> N;
    for (int j = 0; j < N; ++j) {
      int sx, sy, tx, ty;
      cin >> sx >> sy >> tx >> ty >> o[j] >> l[j];
      s[j] = P(sx, sy);
      t[j] = P(tx, ty);
    }
    cout << solve() << endl;
  }
  return 0;
}

Error: WA

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;

using int64 = int64_t;

constexpr double EPS = 1e-8;

struct point {
  double x, y;
  int id;
  point() : x(0), y(0), id(0) {}

  point(double a, double b) : x(a), y(b), id(-1) {}
  point(double a, double b, int c) : x(a), y(b), id(c) {}

  bool operator<(const point &o) const { return x == o.x ? y < o.y : x < o.y; }

  bool operator>(const point &o) const { return x == o.x ? y > o.y : x > o.y; }
};

double put(point p, point l1, point l2) {
  double a = l1.y - l2.y, b = l2.x - l1.x, c = l1.x * l2.y - l2.x * l1.y;
  return a * p.x + b * p.y + c;
}

point intersect(point k1, point k2, point l1, point l2) {
  double sig = put(k1, l1, l2) > 0 ? 1 : -1;
  double x1 = k1.x, y1 = k1.y, x2 = k2.x, y2 = k2.y;
  for (int j = 0; j < 500; ++j) {
    double mid_x = (x1 + x2) / 2, mid_y = (y1 + y2) / 2;
    double val = put(point(mid_x, mid_y), l1, l2);
    if (abs(val) < EPS) {
      return point(mid_x, mid_y);
    } else if (val * sig > 0) {
      x1 = mid_x, y1 = mid_y;
    } else {
      x2 = mid_x, y2 = mid_y;
    }
  }
  return point(x1, x2);
}

bool cross(point k1, point k2, point l1, point l2) {
  bool b1 = put(k1, l1, l2) * put(k2, l1, l2) < 0;
  bool b2 = put(l1, k1, k2) * put(l2, k1, k2) < 0;
  return b1 && b2;
}

int xa, ya, xb, yb, N;
point s[1000], t[1000];
int o[1000], l[1000];

int solve() {
  point start(xa, ya), goal(xb, yb);
  vector<point> itss;
  for (int j = 0; j < N; ++j)
    if (cross(start, goal, s[j], t[j])) {
      point it = intersect(start, goal, s[j], t[j]);
      it.id = j;
      itss.push_back(it);
    }

  sort(begin(itss), end(itss));
  if (start > goal)
    reverse(begin(itss), end(itss));

  int ret = 0, height = -1;
  for (const point &it : itss) {
    int id = it.id;
    int expected = o[id] == 1 ? l[id] : 1 - l[id];
    if (height == -1) {
      height = expected;
    } else if (height != expected) {
      ++ret;
      height = expected;
    }
  }
  return ret;
}

int main() {
  int datasets;
  cin >> datasets;
  for (int d = 0; d < datasets; ++d) {
    cin >> xa >> ya >> xb >> yb >> N;
    for (int j = 0; j < N; ++j) {
      cin >> s[j].x >> s[j].y >> t[j].x >> t[j].y >> o[j] >> l[j];
    }
    cout << solve() << endl;
  }
  return 0;
}