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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <set>
#include <vector>

using namespace std;
typedef long long ll;

typedef long double R;
typedef complex<R> P;

namespace std {
bool operator<(P a, P b) {
  return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
}
bool operator>(P a, P b) { return (b < a); }
} // namespace std

const R EPS = 1e-7;
const R PI = acos((R)(-1));

/*
 -1 -> neg
  0 -> near 0
  1 -> pos
  */
int sgn(R a) {
  if (a < -EPS)
    return -1;
  if (a > EPS)
    return 1;
  return 0;
}

int sgn(R a, R b) { return sgn(b - a); }

bool near(P a, P b) { return !sgn(abs(a - b)); }

R cross(P a, P b) { return a.real() * b.imag() - a.imag() * b.real(); }
R dot(P a, P b) { return a.real() * b.real() + a.imag() * b.imag(); }

R ssqrt(R d) {
  d = max<R>(0, d);
  return sqrt(d);
}

R sacos(R d) {
  d = max<R>(-1, d);
  d = min<R>(1, d);
  return acos(d);
}

R deg2rad(R x) { return x / 180 * PI; }

R rad2deg(R x) { return x / PI * 180; }

//?§???????[0, 2*PI)???
R radNorP(R x) { return fmod(fmod(x, 2 * PI) + 2 * PI, 2 * PI); }

//?§???????[-PI, PI)???
R radNorN(R x) {
  x = radNorP(x);
  if (x >= PI)
    x -= 2 * PI;
  return x;
}

/**
 * radian??§???x???[l, r]?????\\??£????????????????????\\??????
 * 0:OFF
 * 1:IN
 * 2:ON
 */
bool inR(R l, R r, R x) {
  l = radNorP(l);
  r = radNorP(r);
  x = radNorP(x);
  if (!sgn(l, x) || !sgn(r, x))
    return 2;
  if (!sgn(l, r))
    return 0;
  if (sgn(l, r) == 1) {
    if (sgn(l, x) == 1 && sgn(x, r) == 1)
      return 1;
  } else {
    if (sgn(x, r) == 1 || sgn(l, x) == 1)
      return 1;
  }
  return 0;
}

/* 1->cclock
  -1->clock
   0->on
   2->back
  -2->front
  */
int ccw(P a, P b, P c) {
  assert(!near(a, b));
  if (near(a, c) || near(b, c))
    return 0;
  int s = sgn(cross(b - a, c - a));
  if (s)
    return s;
  if (dot(b - a, c - a) < 0)
    return 2;
  if (dot(a - b, c - b) < 0)
    return -2;
  return 0;
}

struct L {
  P x, y;
  L(){};
  L(P x, P y) : x(x), y(y){};
};

P vec(const L &l) { return l.y - l.x; }

R abs(const L &l) { return abs(vec(l)); }

int crossLL(const L &l, const L &m, P &r) {
  L mm = L(m.x - l.x, m.y - l.x);
  mm.x *= polar<R>(1.0, -arg(vec(l)));
  mm.y *= polar<R>(1.0, -arg(vec(l)));
  if (sgn(vec(mm).imag()) == 0) {
    if (sgn(mm.x.imag()) == 0)
      return -1;
    return 0;
  }
  r = mm.x - vec(mm) * (mm.x.imag() / vec(mm).imag());
  r *= polar<R>(1.0, arg(vec(l)));
  r += l.x;
  return 1;
}

int crossSS(const L &l, const L &m, P &r) {
  int u = crossLL(l, m, r);
  if (u == 0)
    return 0;
  if (u == -1) {
    int x = ccw(l.x, l.y, m.x);
    int y = ccw(l.x, l.y, m.y);
    if (x == 0) {
      r = m.x;
      return -1;
    }
    if (y == 0) {
      r = m.y;
      return -1;
    }
    if (x == y)
      return 0;
    r = l.x;
    return -1;
  }
  if (ccw(l.x, l.y, r) == 0 && ccw(m.x, m.y, r) == 0)
    return 1;
  return 0;
}

/*
exec??§res??????????????¢?????\\???
*/
const R INF = 1e12;
template <int V> struct Dijkstra {
  typedef R T;
  typedef pair<T, int> P;
  vector<P> g[V];
  void init() {
    for (int i = 0; i < V; i++) {
      g[i].clear();
    }
  }
  void add(int from, int to, T dist) { g[from].push_back(P(dist, to)); }
  T res[V];
  void exec(int s) {
    fill_n(res, V, INF);
    priority_queue<P, vector<P>, greater<P>> q;
    q.push(P(0, s));
    res[s] = 0;
    while (!q.empty()) {
      P p = q.top();
      q.pop();
      if (res[p.second] < p.first)
        continue;
      for (P e : g[p.second]) {
        if (p.first + e.first < res[e.second]) {
          res[e.second] = p.first + e.first;
          q.push(P(e.first + p.first, e.second));
        }
      }
    }
    return;
  }
};

typedef pair<P, int> E;
const int MN = 55;
Dijkstra<MN * MN * 2> djk;
int n;
L l[MN];
R ar[MN];
P s, t;
vector<E> g[MN];
int xyd2id(int x, int y, int d) { return (y * MN + x) * 2 + d; }
R calc() {
  djk.init();
  for (int i = 0; i < MN; i++) {
    g[i].clear();
  }
  for (int i = 0; i < n; i++) {
    ar[i] = arg(vec(l[i]));
  }
  for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
      P p;
      int u = crossSS(l[i], l[j], p);
      if (u == 0)
        continue;
      //            printf("cross %d %d\\n", i, j);
      g[i].push_back(E(p, j));
      g[j].push_back(E(p, i));
      djk.add(xyd2id(i, j, 0), xyd2id(j, i, 0), abs(radNorN(ar[i] - ar[j])));
      djk.add(xyd2id(i, j, 0), xyd2id(j, i, 1),
              PI - abs(radNorN(ar[i] - ar[j])));
      djk.add(xyd2id(i, j, 1), xyd2id(j, i, 0),
              PI - abs(radNorN(ar[i] - ar[j])));
      djk.add(xyd2id(i, j, 1), xyd2id(j, i, 1), abs(radNorN(ar[i] - ar[j])));
      djk.add(xyd2id(j, i, 0), xyd2id(i, j, 0), abs(radNorN(ar[i] - ar[j])));
      djk.add(xyd2id(j, i, 0), xyd2id(i, j, 1),
              PI - abs(radNorN(ar[i] - ar[j])));
      djk.add(xyd2id(j, i, 1), xyd2id(i, j, 0),
              PI - abs(radNorN(ar[i] - ar[j])));
      djk.add(xyd2id(j, i, 1), xyd2id(i, j, 1), abs(radNorN(ar[i] - ar[j])));
    }
  }
  for (int i = 0; i < n; i++) {
    if (ccw(l[i].x, l[i].y, s) == 0) {
      //            printf("start %d\\n", i);
      g[i].push_back(E(s, MN - 2));
      djk.add(xyd2id(MN - 2, MN - 2, 0), xyd2id(i, MN - 2, 0), 0);
      djk.add(xyd2id(MN - 2, MN - 2, 0), xyd2id(i, MN - 2, 1), 0);
    }
  }
  for (int i = 0; i < n; i++) {
    if (ccw(l[i].x, l[i].y, t) == 0) {
      //            printf("end %d\\n", i);
      g[i].push_back(E(t, MN - 1));
      djk.add(xyd2id(i, MN - 1, 0), xyd2id(MN - 1, MN - 1, 0), 0);
      djk.add(xyd2id(i, MN - 1, 1), xyd2id(MN - 1, MN - 1, 0), 0);
    }
  }
  for (int i = 0; i < n; i++) {
    sort(g[i].begin(), g[i].end(), [&](const E &x, const E &y) {
      return abs(x.first - l[i].x) < abs(y.first - l[i].x);
    });
    for (int j = 0; j < (int)g[i].size() - 1; j++) {
      int x = g[i][j].second, y = g[i][j + 1].second;
      djk.add(xyd2id(i, x, 0), xyd2id(i, y, 0), 0);
      djk.add(xyd2id(i, y, 1), xyd2id(i, x, 1), 0);
      if (sgn(abs(g[i][j].first - l[i].x), abs(g[i][j + 1].first - l[i].x)) ==
          0) {
        djk.add(xyd2id(i, x, 1), xyd2id(i, y, 1), 0);
        djk.add(xyd2id(i, y, 0), xyd2id(i, x, 0), 0);
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (i == j)
        continue;
      djk.add(xyd2id(i, j, 0), xyd2id(i, j, 1), PI);
    }
  }
  djk.exec(xyd2id(MN - 2, MN - 2, 0));
  R res = djk.res[xyd2id(MN - 1, MN - 1, 0)];
  if (res > INF / 2) {
    return -1;
  }
  return rad2deg(res);
}

int main() {
  while (true) {
    cin >> n;
    if (!n)
      break;
    for (int i = 0; i < n; i++) {
      R x1, y1, x2, y2;
      cin >> x1 >> y1 >> x2 >> y2;
      l[i] = L(P(x1, y1), P(x2, y2));
    }
    R sx, sy, tx, ty;
    cin >> sx >> sy >> tx >> ty;
    s = P(sx, sy);
    t = P(tx, ty);
    printf("%.20Lf\\n", calc());
  }
  return 0;
}

Error: -6
226852a8-05e8-4d0b-b8c1-507491110fc8.out: /home/alex/Documents/bug-detection/input/Project_CodeNet/data/p00619/C++/s529237347.cpp:151: int crossSS(const L&, const L&, P&): Assertion `x % 2 == 0' failed.


Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <set>
#include <vector>

using namespace std;
typedef long long ll;

typedef long double R;
typedef complex<R> P;

namespace std {
bool operator<(P a, P b) {
  return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
}
bool operator>(P a, P b) { return (b < a); }
} // namespace std

const R EPS = 1e-10;
const R PI = acos((R)(-1));

/*
 -1 -> neg
  0 -> near 0
  1 -> pos
  */
int sgn(R a) {
  if (a < -EPS)
    return -1;
  if (a > EPS)
    return 1;
  return 0;
}

int sgn(R a, R b) { return sgn(b - a); }

bool near(P a, P b) { return !sgn(abs(a - b)); }

R cross(P a, P b) { return a.real() * b.imag() - a.imag() * b.real(); }
R dot(P a, P b) { return a.real() * b.real() + a.imag() * b.imag(); }

R ssqrt(R d) {
  d = max<R>(0, d);
  return sqrt(d);
}

R sacos(R d) {
  d = max<R>(-1, d);
  d = min<R>(1, d);
  return acos(d);
}

R deg2rad(R x) { return x / 180 * PI; }

R rad2deg(R x) { return x / PI * 180; }

//?§???????[0, 2*PI)???
R radNorP(R x) { return fmod(fmod(x, 2 * PI) + 2 * PI, 2 * PI); }

//?§???????[-PI, PI)???
R radNorN(R x) {
  x = radNorP(x);
  if (x >= PI)
    x -= 2 * PI;
  return x;
}

/**
 * radian??§???x???[l, r]?????\\??£????????????????????\\??????
 * 0:OFF
 * 1:IN
 * 2:ON
 */
bool inR(R l, R r, R x) {
  l = radNorP(l);
  r = radNorP(r);
  x = radNorP(x);
  if (!sgn(l, x) || !sgn(r, x))
    return 2;
  if (!sgn(l, r))
    return 0;
  if (sgn(l, r) == 1) {
    if (sgn(l, x) == 1 && sgn(x, r) == 1)
      return 1;
  } else {
    if (sgn(x, r) == 1 || sgn(l, x) == 1)
      return 1;
  }
  return 0;
}

/* 1->cclock
  -1->clock
   0->on
   2->back
  -2->front
  */
int ccw(P a, P b, P c) {
  assert(!near(a, b));
  if (near(a, c) || near(b, c))
    return 0;
  int s = sgn(cross(b - a, c - a));
  if (s)
    return s;
  if (dot(b - a, c - a) < 0)
    return 2;
  if (dot(a - b, c - b) < 0)
    return -2;
  return 0;
}

struct L {
  P x, y;
  L(){};
  L(P x, P y) : x(x), y(y){};
};

P vec(const L &l) { return l.y - l.x; }

R abs(const L &l) { return abs(vec(l)); }

int crossLL(const L &l, const L &m, P &r) {
  L mm = L(m.x - l.x, m.y - l.x);
  mm.x *= polar<R>(1.0, -arg(vec(l)));
  mm.y *= polar<R>(1.0, -arg(vec(l)));
  if (sgn(vec(mm).imag()) == 0)
    return -1;
  r = mm.x - vec(mm) * (mm.x.imag() / vec(mm).imag());
  r *= polar<R>(1.0, arg(vec(l)));
  r += l.x;
  return 1;
}

int crossSS(const L &l, const L &m, P &r) {
  int u = crossLL(l, m, r);
  if (u == -1) {
    int x = ccw(l.x, l.y, m.x);
    int y = ccw(l.x, l.y, m.y);
    assert(x % 2 == 0);
    assert(y % 2 == 0);
    if (x == 0) {
      r = m.x;
      return -1;
    }
    if (y == 0) {
      r = m.y;
      return -1;
    }
    if (x == y)
      return 0;
    r = l.x;
    return -1;
  }
  if (ccw(l.x, l.y, r) == 0 && ccw(m.x, m.y, r) == 0)
    return 1;
  return 0;
}

/*
exec??§res??????????????¢?????\\???
*/
const R INF = 1e12;
template <int V> struct Dijkstra {
  typedef R T;
  typedef pair<T, int> P;
  vector<P> g[V];
  void init() {
    for (int i = 0; i < V; i++) {
      g[i].clear();
    }
  }
  void add(int from, int to, T dist) { g[from].push_back(P(dist, to)); }
  T res[V];
  void exec(int s) {
    fill_n(res, V, INF);
    priority_queue<P, vector<P>, greater<P>> q;
    q.push(P(0, s));
    res[s] = 0;
    while (!q.empty()) {
      P p = q.top();
      q.pop();
      if (res[p.second] < p.first)
        continue;
      for (P e : g[p.second]) {
        if (p.first + e.first < res[e.second]) {
          res[e.second] = p.first + e.first;
          q.push(P(e.first + p.first, e.second));
        }
      }
    }
    return;
  }
};

typedef pair<P, int> E;
const int MN = 55;
Dijkstra<MN * MN * 2> djk;
int n;
L l[MN];
R ar[MN];
P s, t;
vector<E> g[MN];
int xyd2id(int x, int y, int d) { return (y * MN + x) * 2 + d; }
R calc() {
  djk.init();
  for (int i = 0; i < n; i++) {
    ar[i] = arg(vec(l[i]));
  }
  for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
      P p;
      int u = crossSS(l[i], l[j], p);
      if (u == 0)
        continue;
      g[i].push_back(E(p, j));
      g[j].push_back(E(p, i));
      djk.add(xyd2id(i, j, 0), xyd2id(j, i, 0), abs(radNorN(ar[i] - ar[j])));
      djk.add(xyd2id(i, j, 0), xyd2id(j, i, 1),
              PI - abs(radNorN(ar[i] - ar[j])));
      djk.add(xyd2id(i, j, 1), xyd2id(j, i, 0),
              PI - abs(radNorN(ar[i] - ar[j])));
      djk.add(xyd2id(i, j, 1), xyd2id(j, i, 1), abs(radNorN(ar[i] - ar[j])));
    }
  }
  for (int i = 0; i < n; i++) {
    if (ccw(l[i].x, l[i].y, s) == 0) {
      g[i].push_back(E(s, MN - 2));
      djk.add(xyd2id(MN - 2, MN - 2, 0), xyd2id(i, MN - 2, 0), 0);
      djk.add(xyd2id(MN - 2, MN - 2, 0), xyd2id(i, MN - 2, 1), 0);
    }
  }
  for (int i = 0; i < n; i++) {
    if (ccw(l[i].x, l[i].y, t) == 0) {
      g[i].push_back(E(t, MN - 1));
      djk.add(xyd2id(i, MN - 1, 0), xyd2id(MN - 1, MN - 1, 0), 0);
      djk.add(xyd2id(i, MN - 1, 1), xyd2id(MN - 1, MN - 1, 0), 0);
    }
  }
  for (int i = 0; i < n; i++) {
    sort(g[i].begin(), g[i].end(), [&](const E &x, const E &y) {
      return abs(x.first - l[i].x) < abs(y.first - l[i].x);
    });
    for (int j = 0; j < (int)g[i].size() - 1; j++) {
      int x = g[i][j].second, y = g[i][j + 1].second;
      djk.add(xyd2id(i, x, 0), xyd2id(i, y, 0), 0);
      djk.add(xyd2id(i, y, 1), xyd2id(i, x, 1), 0);
      if (sgn(abs(g[i][j].first - l[i].x), abs(g[i][j + 1].first - l[i].x)) ==
          0) {
        djk.add(xyd2id(i, x, 1), xyd2id(i, y, 1), 0);
        djk.add(xyd2id(i, y, 0), xyd2id(i, x, 0), 0);
      }
    }
  }
  djk.exec(xyd2id(MN - 2, MN - 2, 0));
  R res = djk.res[xyd2id(MN - 1, MN - 1, 0)];
  if (res > INF / 2) {
    return -1;
  }
  return rad2deg(res);
}

int main() {
  while (true) {
    cin >> n;
    if (!n)
      break;
    for (int i = 0; i < n; i++) {
      R x1, y1, x2, y2;
      cin >> x1 >> y1 >> x2 >> y2;
      l[i] = L(P(x1, y1), P(x2, y2));
    }
    R sx, sy, tx, ty;
    cin >> sx >> sy >> tx >> ty;
    s = P(sx, sy);
    t = P(tx, ty);
    printf("%.20Lf\\n", calc());
  }
  return 0;
}