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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <iostream>
#include <list>
#include <set>
#include <vector>

using namespace std;
typedef double elem;
typedef complex<elem> point, vec;
typedef pair<point, point> line, hline, seg, pp;
enum CCW { BACK = 0x01, FRONT = 0x02, OVER = 0x04, LEFT = 0x08, RIGHT = 0x10 };

const elem infty = 1e40;
const double eps = 1e-8;
bool eq(double a, double b) { return abs(b - a) < eps; }
elem cross(vec a, vec b) { return a.real() * b.imag() - a.imag() * b.real(); }
elem dot(vec a, vec b) { return a.real() * b.real() + a.imag() * b.imag(); }
elem dist_l(line l, point x) {
  return abs(cross(l.second - l.first, x - l.first)) / abs(l.second - l.first);
}

inline int ccw(const point &a, point b, point x) {
  b -= a;
  x -= a;
  if (eq(cross(b, x), 0) && dot(b, x) < 0)
    return BACK;
  if (eq(cross(b, x), 0) && abs(b) < abs(x))
    return FRONT;
  if (eq(cross(b, x), 0))
    return OVER;
  if (cross(b, x) > 0)
    return LEFT;
  else
    return RIGHT;
}

inline bool intersectedSS(const seg &a, const seg &b) {
  int cwaf = ccw(a.first, a.second, b.first);
  int cwbf = ccw(b.first, b.second, a.first);
  int cwas = ccw(a.first, a.second, b.second);
  int cwbs = ccw(b.first, b.second, a.second);
  if (cwaf == OVER || cwas == OVER || cwbf == OVER || cwbs == OVER)
    return true;
  return (cwaf | cwas) == (LEFT | RIGHT) && (cwbf | cwbs) == (LEFT | RIGHT);
}

point intersectionSS(seg a, seg b) {
  elem d1 = dist_l(b, a.first);
  elem d2 = dist_l(b, a.second);
  return a.first + (d1 / (d1 + d2)) * (a.second - a.first);
}

bool intersectionSS(seg a, seg b, point &ret) {
  return intersectedSS(a, b) ? ret = intersectionSS(a, b), true : false;
}

bool validPoint(const point &p) {
  return -2002 <= p.real() && p.real() <= 2002 && -2002 <= p.imag() &&
         p.imag() <= 2002;
}

bool compElemPair(const pair<elem, elem> &a, const pair<elem, elem> &b) {
  if (!eq(a.first, b.first))
    return a.first < b.first;
  if (!eq(a.second, b.second))
    return a.second < b.second;
  // assert(false);
  return false;
}

int main() {
  int m;
  while (cin >> m && m) {
    vector<point> vp;
    int res = 0;
    for (int i = 0; i < m; ++i) {
      elem x, y;
      cin >> x >> y;
      // assert(-2000<=x&&x<=2000&&-2000<=y&&y<=2000);
      vp.push_back(point(x, y));
    }

    for (int y = -2000; y < 2000; ++y) {
      seg lower(point(-2001, y), point(2001, y));
      seg center(point(-2001, y + 0.5), point(2001, y + 0.5));
      seg upper(point(-2001, y + 1), point(2001, y + 1));
      vector<pair<elem, elem>> vx;

      for (int i = 0; i < (int)vp.size(); ++i) {
        point a = vp[i];
        point b = vp[(i + 1) % vp.size()];
        seg s(a, b);

        if (intersectedSS(s, center)) {
          point is;
          elem left, right;
          if (intersectionSS(lower, s, is) && validPoint(is)) {
            left = is.real();
            right = is.real();
          }
          if (intersectionSS(upper, s, is) && validPoint(is)) {
            left = min(left, is.real());
            right = max(right, is.real());
          }
          vx.push_back(make_pair(left, right));
        }
      }

      sort(vx.begin(), vx.end(), compElemPair);

      int prev = -2001;
      for (int i = 0; i < (int)vx.size() - 1; i += 2) {
        int left_x = (int)floor(min(vx[i].first, vx[i].second) + eps);
        int right_x = (int)ceil(max(vx[i + 1].first, vx[i + 1].second) - eps);
        int tmp = right_x - max(left_x, prev);
        if (tmp >= 0)
          res += tmp;
        prev = right_x;
      }
    }
    cout << res << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <iostream>
#include <list>
#include <set>
#include <vector>

using namespace std;
typedef double elem;
typedef complex<elem> point, vec;
typedef pair<point, point> line, hline, seg, pp;
enum CCW { BACK = 0x01, FRONT = 0x02, OVER = 0x04, LEFT = 0x08, RIGHT = 0x10 };

const elem infty = 1e40;
const double eps = 1e-8;
bool eq(double a, double b) { return abs(b - a) < eps; }
elem cross(vec a, vec b) { return a.real() * b.imag() - a.imag() * b.real(); }
elem dot(vec a, vec b) { return a.real() * b.real() + a.imag() * b.imag(); }
elem dist_l(line l, point x) {
  return abs(cross(l.second - l.first, x - l.first)) / abs(l.second - l.first);
}

inline int ccw(const point &a, point b, point x) {
  b -= a;
  x -= a;
  if (eq(cross(b, x), 0) && dot(b, x) < 0)
    return BACK;
  if (eq(cross(b, x), 0) && abs(b) < abs(x))
    return FRONT;
  if (eq(cross(b, x), 0))
    return OVER;
  if (cross(b, x) > 0)
    return LEFT;
  else
    return RIGHT;
}

inline bool intersectedSS(const seg &a, const seg &b) {
  int cwaf = ccw(a.first, a.second, b.first);
  int cwbf = ccw(b.first, b.second, a.first);
  int cwas = ccw(a.first, a.second, b.second);
  int cwbs = ccw(b.first, b.second, a.second);
  if (cwaf == OVER || cwas == OVER || cwbf == OVER || cwbs == OVER)
    return true;
  return (cwaf | cwas) == (LEFT | RIGHT) && (cwbf | cwbs) == (LEFT | RIGHT);
}

point intersectionSS(seg a, seg b) {
  elem d1 = dist_l(b, a.first);
  elem d2 = dist_l(b, a.second);
  return a.first + (d1 / (d1 + d2)) * (a.second - a.first);
}

bool intersectionSS(seg a, seg b, point &ret) {
  return intersectedSS(a, b) ? ret = intersectionSS(a, b), true : false;
}

bool validPoint(const point &p) {
  return -2002 <= p.real() && p.real() <= 2002 && -2002 <= p.imag() &&
         p.imag() <= 2002;
}

bool compElemPair(const pair<elem, elem> &a, const pair<elem, elem> &b) {
  if (!eq(a.first, b.first))
    return a.first < b.first;
  if (!eq(a.second, b.second))
    return a.second < b.second;
  assert(false);
  return false;
}

int main() {
  int m;
  while (cin >> m && m) {
    vector<point> vp;
    int res = 0;
    for (int i = 0; i < m; ++i) {
      elem x, y;
      cin >> x >> y;
      // assert(-2000<=x&&x<=2000&&-2000<=y&&y<=2000);
      vp.push_back(point(x, y));
    }

    for (int y = -2000; y < 2000; ++y) {
      seg lower(point(-2001, y), point(2001, y));
      seg center(point(-2001, y + 0.5), point(2001, y + 0.5));
      seg upper(point(-2001, y + 1), point(2001, y + 1));
      vector<pair<elem, elem>> vx;

      for (int i = 0; i < (int)vp.size(); ++i) {
        point a = vp[i];
        point b = vp[(i + 1) % vp.size()];
        seg s(a, b);

        if (intersectedSS(s, center)) {
          point is;
          elem left, right;
          if (intersectionSS(lower, s, is) && validPoint(is)) {
            left = is.real();
            right = is.real();
          }
          if (intersectionSS(upper, s, is) && validPoint(is)) {
            left = min(left, is.real());
            right = max(right, is.real());
          }
          vx.push_back(make_pair(left, right));
        }
      }

      sort(vx.begin(), vx.end(), compElemPair);

      int prev = -2001;
      for (int i = 0; i < (int)vx.size() - 1; i += 2) {
        int left_x = (int)floor(min(vx[i].first, vx[i].second) + eps);
        int right_x = (int)ceil(max(vx[i + 1].first, vx[i + 1].second) - eps);
        int tmp = right_x - max(left_x, prev);
        if (tmp >= 0)
          res += tmp;
        prev = right_x;
      }
    }
    cout << res << endl;
  }
  return 0;
}