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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>

using namespace std;

const double EPS = 1e-8;

int dcmp(double d) {
  if (fabs(d) < EPS) {
    return 0;
  } else {
    return d < 0 ? -1 : 1;
  }
}

struct Vector {
  double x, y;
  Vector(double x = 0, double y = 0) : x(x), y(y) {}

  bool operator<(const Vector &other) const {
    return dcmp(y - other.y) != 0 ? y < other.y : dcmp(x - other.x) < 0;
  }
};

typedef Vector Point;

struct PointCmp {
  bool operator()(const Point &a, const Point &b) {
    return (dcmp(a.y - b.y) < 0 ||
            (dcmp(a.y - b.y) == 0 && dcmp(a.x - b.x) < 0));
  }
};

// struct PointCmp1 {
//     bool operator()(const Point& a, const Point &b) {
//         return (dcmp(a.x - b.x) < 0 ||
//                 (dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) < 0));
//     }
// };

Vector operator-(const Vector &a, const Vector &b) {
  return Vector(a.x - b.x, a.y - b.y);
}

double cross(const Vector &a, const Vector &b) { return a.x * b.y - a.y * b.x; }

double ccw(const Point &a, const Point &b, const Point &c) {
  return cross(b - a, c - a);
}

int main() {
  int n;
  cin >> n;
  vector<Point> p(n);

  for (int i = 0; i < n; i++) {
    cin >> p[i].x >> p[i].y;
  }
  sort(p.begin(), p.end());

  vector<Point> ch(n + 1);
  int m = 0;
  for (int i = 0; i < n; i++) {
    while (m > 1 && dcmp(ccw(ch[m - 2], ch[m - 1], p[i])) < 0) {
      m--;
    }
    ch[m++] = p[i];
  }
  int k = m;
  for (int i = n - 2; i >= 0; i--) {
    while (m > k && dcmp(ccw(ch[m - 2], ch[m - 1], p[i])) < 0) {
      m--;
    }
    ch[m++] = p[i];
  }

  if (n > 1) {
    m--;
  }

  cout << m << endl;

  for (int i = 0; i < m; i++) {
    cout << ch[i].x << " " << ch[i].y << endl;
  }

  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>

using namespace std;

const double EPS = 1e-8;

int dcmp(double d) {
  if (fabs(d) < EPS) {
    return 0;
  } else {
    return d < 0 ? -1 : 1;
  }
}

struct Vector {
  double x, y;
  Vector(double x = 0, double y = 0) : x(x), y(y) {}

  bool operator<(const Vector &other) const {
    return dcmp(y - other.y) != 0 ? y < other.y : dcmp(x - other.x) < 0;
  }
};

typedef Vector Point;

struct PointCmp {
  bool operator()(const Point &a, const Point &b) {
    return (dcmp(a.y - b.y) < 0 ||
            (dcmp(a.y - b.y) == 0 && dcmp(a.x - b.x) < 0));
  }
};

// struct PointCmp1 {
//     bool operator()(const Point& a, const Point &b) {
//         return (dcmp(a.x - b.x) < 0 ||
//                 (dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) < 0));
//     }
// };

Vector operator-(const Vector &a, const Vector &b) {
  return Vector(a.x - b.x, a.y - b.y);
}

double cross(const Vector &a, const Vector &b) { return a.x * b.y - a.y * b.x; }

double ccw(const Point &a, const Point &b, const Point &c) {
  return cross(b - a, c - a);
}

int main() {
  int n;
  cin >> n;
  vector<Point> p(n);

  for (int i = 0; i < n; i++) {
    cin >> p[i].x >> p[i].y;
  }
  sort(p.begin(), p.end());

  vector<Point> ch(n);
  int m = 0;
  for (int i = 0; i < n; i++) {
    while (m > 1 && dcmp(ccw(ch[m - 2], ch[m - 1], p[i])) < 0) {
      // cout << "remove " << ch[m - 1].x << " " << ch[m - 1].y << endl;
      m--;
    }
    ch[m++] = p[i];
    // cout << "Add " << p[i].x << " " << p[i].y << endl;
  }
  // cout << " upper " << endl;
  int k = m;
  for (int i = n - 2; i >= 0; i--) {
    while (m > k && dcmp(ccw(ch[m - 2], ch[m - 1], p[i])) < 0) {
      // cout << "remove " << ch[m - 1].x << " " << ch[m - 1].y << endl;
      m--;
    }
    ch[m++] = p[i];
    // cout << "Add " << p[i].x << " " << p[i].y << endl;
  }

  if (n > 1) {
    m--;
  }

  cout << m << endl;

  for (int i = 0; i < m; i++) {
    cout << ch[i].x << " " << ch[i].y << endl;
  }

  return 0;
}