Problem p00143 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef vector<PII> VPII;
typedef istringstream ISS;
typedef ostringstream OSS;

#define REP(i, m, n) for (int i = (int)(m); i < (int)(n); ++i)
#define FOR(v, c) for (auto &v : c)
#define EACH(it, c) for (auto it = c.begin(); it != c.end(); ++it)
#define ALL(c) (c).begin(), (c).end()
#define DRANGE(c, p) (c).begin(), (c).begin() + p, (c).end()

#define PB(n) push_back(n)
#define MP(a, b) make_pair((a), (b))
#define EXIST(c, e) ((c).find(e) != (c).end())

#define fst first
#define snd second

#define DUMP(x) cerr << #x << " = " << (x) << endl
#define DEBUG(x)                                                               \
  cerr << __FILE__ << ":" << __LINE__ << ": " << #x << " = " << (x) << endl

#include <complex>
typedef complex<double> Point;
const double EPS = 1e-8;

// 入力ストリームから実数二つをとって Point へ
istream &operator>>(istream &s, Point &a) {
  double r, i;
  s >> r >> i;
  a = Point(r, i);
  return s;
}

// 外積（クロス積）
double cross(const Point &a, const Point &b) {
  return a.real() * b.imag() - a.imag() * b.real();
}

// CCW 関数　a -> b -> c と進むとき、反時計回りなら 1, 直進なら 0, 時計回りなら
// -1 include : cross
int ccw(const Point &a, const Point &b, const Point &c) {
  if (cross((b - a), (c - a)) < -EPS) {
    return -1;
  } else if (EPS < cross((b - a), (c - a))) {
    return 1;
  } else {
    return 0;
  }
}

// 点 p が多角形 qs の内部にあるか ( Winding Number Algorithm) :TODO
// include : ccw
bool point_in_polygon(const Point &p, const vector<Point> &qs) {
  const int N = qs.size();

  int wn = 0;
  for (int i = 0; i < N; ++i) {
    const Point &s = qs[i], &t = qs[(i + 1) % N];
    if (s.imag() - EPS <= t.imag() && s.imag() - EPS < p.imag() &&
        p.imag() + EPS < t.imag()) // 上向きの辺
    {
      wn += ccw(s, p, t) == -1;
    } else if (t.imag() - EPS <= s.imag() && t.imag() - EPS < p.imag() &&
               p.imag() + EPS < s.imag()) {
      wn -= ccw(t, p, s) == -1;
    }
  }
  return wn;
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int n;
  cin >> n;
  REP(i, 0, n) {
    vector<Point> tri(3);
    REP(j, 0, 3) { cin >> tri[i]; }
    Point s, t;
    cin >> s >> t;

    cout << (point_in_polygon(s, tri) ^ point_in_polygon(t, tri) ? "OK" : "NG")
         << endl;
  }

  return 0;
}

Fixed submission:
#include <algorithm>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef vector<PII> VPII;
typedef istringstream ISS;
typedef ostringstream OSS;

#define REP(i, m, n) for (int i = (int)(m); i < (int)(n); ++i)
#define FOR(v, c) for (auto &v : c)
#define EACH(it, c) for (auto it = c.begin(); it != c.end(); ++it)
#define ALL(c) (c).begin(), (c).end()
#define DRANGE(c, p) (c).begin(), (c).begin() + p, (c).end()

#define PB(n) push_back(n)
#define MP(a, b) make_pair((a), (b))
#define EXIST(c, e) ((c).find(e) != (c).end())

#define fst first
#define snd second

#define DUMP(x) cerr << #x << " = " << (x) << endl
#define DEBUG(x)                                                               \
  cerr << __FILE__ << ":" << __LINE__ << ": " << #x << " = " << (x) << endl

#include <complex>
typedef complex<double> Point;
const double EPS = 1e-8;

// 入力ストリームから実数二つをとって Point へ
istream &operator>>(istream &s, Point &a) {
  double r, i;
  s >> r >> i;
  a = Point(r, i);
  return s;
}

// 外積（クロス積）
double cross(const Point &a, const Point &b) {
  return a.real() * b.imag() - a.imag() * b.real();
}

// CCW 関数　a -> b -> c と進むとき、反時計回りなら 1, 直進なら 0, 時計回りなら
// -1 include : cross
int ccw(const Point &a, const Point &b, const Point &c) {
  if (cross((b - a), (c - a)) < -EPS) {
    return -1;
  } else if (EPS < cross((b - a), (c - a))) {
    return 1;
  } else {
    return 0;
  }
}

// 点 p が多角形 qs の内部にあるか ( Winding Number Algorithm) :TODO
// include : ccw
bool point_in_polygon(const Point &p, const vector<Point> &qs) {
  const int N = qs.size();

  int wn = 0;
  for (int i = 0; i < N; ++i) {
    const Point &s = qs[i], &t = qs[(i + 1) % N];
    if (s.imag() - EPS <= t.imag() && s.imag() - EPS < p.imag() &&
        p.imag() + EPS < t.imag()) // 上向きの辺
    {
      wn += ccw(s, p, t) == -1;
    } else if (t.imag() - EPS <= s.imag() && t.imag() - EPS < p.imag() &&
               p.imag() + EPS < s.imag()) {
      wn -= ccw(t, p, s) == -1;
    }
  }
  return wn;
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int n;
  cin >> n;
  REP(i, 0, n) {
    vector<Point> tri(3);
    REP(j, 0, 3) { cin >> tri[j]; }
    Point s, t;
    cin >> s >> t;

    cout << (point_in_polygon(s, tri) ^ point_in_polygon(t, tri) ? "OK" : "NG")
         << endl;
  }

  return 0;
}