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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <iterator>
#include <limits>
#include <utility>
#include <vector>

using namespace std;

typedef struct {
  double x, y;
} pt;

typedef pair<pt, pt> seg;

seg mkseg(double ax, double ay, double bx, double by) {
  pt a = {ax, ay};
  pt b = {bx, by};
  return seg(a, b);
}

double inf = numeric_limits<double>::infinity();
double eps = pow(10, -9);

pt seg_cross(seg a, seg b) {
  double A = (a.second.x - a.first.x) / (a.second.y - a.first.y);
  double B = (b.second.x - b.first.x) / (b.second.y - b.first.y);

  // cerr << "A=" << A << " B=" << B << endl;

  if (A == inf || A == -inf) {
    double y = a.first.y;
    double x = B * (y - b.first.y) + b.first.x;
    pt p = {x, y};
    return p;
  }

  if (B == inf || B == -inf) {
    double y = b.first.y;
    double x = A * (y - a.first.y) + a.first.x;
    pt p = {x, y};
    return p;
  }

  double y = (A * a.first.y - B * b.first.y + b.first.x - a.first.x) / (A - B);
  double x_ = A * (y - a.first.y) + a.first.x;
  double x = B * (y - b.first.y) + b.first.x;
  pt p = {x, y};
  return p;
}

void solve() {
  int ax, ay, bx, by;
  cin >> ax >> ay >> bx >> by;

  seg new_seg = mkseg(ax, ay, bx, by);
  double nminx = min(ax, bx);
  double nmaxx = max(ax, bx);
  double nminy = min(ay, by);
  double nmaxy = max(ay, by);

  int n;
  cin >> n;

  vector<pair<pt, bool>> pts;

  while (n--) {
    int ax_, ay_, bx_, by_;
    int pos, owner;
    cin >> ax_ >> ay_ >> bx_ >> by_ >> pos >> owner;

    seg s = mkseg(ax_, ay_, bx_, by_);

    double minx = max(nminx, double(min(ax_, bx_))) - eps;
    double maxx = min(nmaxx, double(max(ax_, bx_))) + eps;
    double miny = max(nminy, double(min(ay_, by_))) - eps;
    double maxy = min(nmaxy, double(max(ay_, by_))) + eps;

    pt c = seg_cross(new_seg, s);
    // cerr << "CROSS AT " << c.x << "," << c.y << endl;

    bool flag = (pos == 1) ^ (owner == 1);
    if (minx <= c.x && c.x <= maxx && miny <= c.y && c.y <= maxy) {
      // cerr << "PUSH " << c.x << "," << c.y << endl;
      pts.push_back(make_pair(c, flag));
    }
  }

  struct {
    bool operator()(pair<pt, bool> a, pair<pt, bool> b) {
      return a.first.x == b.first.x ? a.first.y < b.first.y
                                    : a.first.x < b.first.x;
    }
  } by_x;

  sort(pts.begin(), pts.end(), by_x);

  int curr_pos = -1;
  int cnt = 0;
  for (vector<pair<pt, bool>>::iterator it = pts.begin(); it != pts.end();
       ++it) {
    pair<pt, bool> p = *it;
    // cerr << "FOUND " << p.first.x << " " << p.first.y << " " << p.second <<
    // endl;
    if (curr_pos != -1) {
      if (curr_pos != p.second) {
        cnt++;
      }
    }
    curr_pos = p.second;
  }
  cout << cnt << endl;
}

int main() {
  int N;
  cin >> N;
  while (N--) {
    solve();
  }
}

Error: 0
CROSS AT -5,1
PUSH -5,1
CROSS AT -3,1
PUSH -3,1
CROSS AT 5,1
PUSH 5,1
CROSS AT 3,1
PUSH 3,1
FOUND -5 1 1
FOUND -3 1 1
FOUND 3 1 0
FOUND 5 1 0
CROSS AT 4,8
PUSH 4,8
CROSS AT 4,8
PUSH 4,8
CROSS AT 6,10
PUSH 6,10
CROSS AT 2,6
PUSH 2,6
CROSS AT 1,5
PUSH 1,5
CROSS AT -5,-1
PUSH -5,-1
CROSS AT -4,0
PUSH -4,0
CROSS AT -1,3
PUSH -1,3
FOUND -5 -1 1
FOUND -4 0 1
FOUND -1 3 1
FOUND 1 5 0
FOUND 2 6 0
FOUND 4 8 0
FOUND 4 8 1
FOUND 6 10 0


Fixed submission:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <limits>
#include <utility>
#include <vector>

using namespace std;

typedef struct {
  double x, y;
} pt;

typedef pair<pt, pt> seg;

seg mkseg(double ax, double ay, double bx, double by) {
  pt a = {ax, ay};
  pt b = {bx, by};
  return seg(a, b);
}

double inf = numeric_limits<double>::infinity();

pt seg_cross(seg a, seg b) {
  double A = (a.second.x - a.first.x) / (a.second.y - a.first.y);
  double B = (b.second.x - b.first.x) / (b.second.y - b.first.y);

  if (A == inf) {
    double y = a.second.y;
    double x = B * (y - b.first.y) + b.first.x;
    pt p = {x, y};
    return p;
  }

  if (B == inf) {
    double y = b.second.y;
    double x = A * (y - a.first.y) + a.first.x;
    pt p = {x, y};
    return p;
  }

  double y = (A * a.first.y - B * b.first.y + b.first.x - a.first.x) / (A - B);
  double x = A * (y - a.first.y) + a.first.x;
  pt p = {x, y};
  return p;
}

void solve() {
  int ax, ay, bx, by;
  cin >> ax >> ay >> bx >> by;

  seg new_seg = mkseg(ax, ay, bx, by);

  int n;
  cin >> n;

  vector<pair<pt, bool>> pts;

  while (n--) {
    int ax_, ay_, bx_, by_;
    int pos, owner;
    cin >> ax_ >> ay_ >> bx_ >> by_ >> pos >> owner;

    seg s = mkseg(ax_, ay_, bx_, by_);

    double minx = min(ax_, bx_);
    double maxx = max(ax_, bx_);

    pt c = seg_cross(new_seg, s);
    cerr << "CROSS AT " << c.x << "," << c.y << endl;

    bool flag = (pos == 1) ^ (owner == 1);
    if (minx <= c.x && c.x <= maxx && min(ax, bx) <= c.x &&
        c.x <= max(ax, bx)) {
      cerr << "PUSH " << c.x << "," << c.y << endl;
      pts.push_back(make_pair(c, flag));
    }

    // route r;
    // line l = line_from_point(ax_, ay_, bx_, by_);
    // r.minx = min(ax_, bx_);
    // r.maxx = max(ax_, bx_);
    // r.flag = (pos == 1) ^ (owner == 1);

    // point cp = cross_point(new_line, l);
    // double cpx = cp.first;
    // if (r.minx <= cpx && cpx <= r.maxx && ax <= cpx && cpx <= bx) {
    //     cross_points.push_back(make_pair(cp, r.flag));
    // }
  }

  struct {
    bool operator()(pair<pt, bool> a, pair<pt, bool> b) {
      return a.first.x < b.first.x;
    }
  } by_x;

  sort(pts.begin(), pts.end(), by_x);

  int curr_pos = -1;
  int cnt = 0;
  for (vector<pair<pt, bool>>::iterator it = pts.begin(); it != pts.end();
       it++) {
    pair<pt, bool> p = *it;
    cerr << "FOUND " << p.first.x << " " << p.first.y << " " << p.second
         << endl;
    if (curr_pos != -1) {
      if (curr_pos != p.second) {
        cnt++;
      }
    }
    curr_pos = p.second;
  }
  cout << cnt << endl;

  /*
  struct {
      bool operator()(pair<point, bool> a, pair<point, bool> b) {
          return a.first.first < b.first.first;
      }
  } by_x;

  sort(cross_points.begin(), cross_points.end(), by_x);

  int curr_pos = -1;
  int cnt = 0;
  for (vector< pair<point, bool> >::iterator it = cross_points.begin(); it !=
  cross_points.end(); it++) { pair<point, bool> p = *it;
      // cout << p.first.first << " " << p.first.second << " " << p.second <<
  endl; if (curr_pos != -1) { if (curr_pos != p.second) { cnt++;
          }
      }
      curr_pos = p.second;
  }
  cout << cnt << endl;
  */
}

int main() {
  int N;
  cin >> N;
  while (N--) {
    solve();
  }
}