Go: package main

import (
	"bufio"
	"os"
	"strconv"
	"strings"
	"fmt"
)

var scanner = bufio.NewScanner(os.Stdin)

func main() {
	scanner.Scan()
	n, _ := strconv.Atoi(scanner.Text())
	for i := 0; i < n; i++ {
		scanner.Scan()
		input := strings.Split(scanner.Text(), " ")
		buf := make([]float64, len(input))
		for j := range buf {
			buf[j], _ = strconv.ParseFloat(input[j], 64)
		}
		p1 := complex(buf[0], buf[1])
		p2 := complex(buf[2], buf[3])
		p3 := complex(buf[4], buf[5])
		pk := complex(buf[6], buf[7])
		ps := complex(buf[8], buf[9])
		kin := isAtSameSide(p3, pk, []complex128{p1, p2}) &&
			isAtSameSide(p1, pk, []complex128{p2, p3}) &&
			isAtSameSide(p2, pk, []complex128{p3, p1})
		sin := isAtSameSide(p3, ps, []complex128{p1, p2}) &&
			isAtSameSide(p1, ps, []complex128{p2, p3}) &&
			isAtSameSide(p2, ps, []complex128{p3, p1})
		if (kin || sin) && !(kin && sin) {
			fmt.Println("OK")
		} else {
			fmt.Println("NG")
		}
	}
}

func isAtSameSide(a, b complex128, line []complex128) bool {
	sa := (real(line[1]) - real(line[0]))*(imag(a)-imag(line[0]))+
		(imag(line[1])-imag(line[0]))*(real(line[0])-real(a))
	sb := (real(line[1]) - real(line[0]))*(imag(b)-imag(line[0]))+
		(imag(line[1])-imag(line[0]))*(real(line[0])-real(b))
	return (sa > 0 && sb > 0) || (sa < 0 && sb < 0)
}

C++: #include <iostream>
#include <stdio.h>
#include <fstream>
#include <algorithm>
#include <string>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <limits.h>
#include <math.h>
#define rep(i,n) for (int i = 0; (i) < (n); ++ (i))
#define EPS 1e-5
using namespace std;

int main(void){
    int n;
    cin >> n;
    rep(i,n) {
        int count = 0;
        double x[5],y[5],a,b,c,d,p,q,det,ansx;
        for(int k=0;k<5;k++) {
            cin >> x[k] >> y[k];
        }
        rep(j,3) {
            if(j != 2) {
                a = y[j]-y[j+1];  b = x[j+1]-x[j];
                p = x[j+1]*y[j]-x[j]*y[j+1];
                c = y[3]-y[4];  d = x[4]-x[3];
                q = x[4]*y[3]-x[3]*y[4];
                //係数についての行列式
                det = a*d-c*b;
                //det=0で解は存在しない(この問題については２線分は同一直線上にないから
                if(fabs(det) > EPS){
                    ansx = (d*p - b*q)/det;
                    //ansxがどちらの線分のx座標範囲にも含まれるかを判定
                    if((x[j] - ansx)*(x[j+1] - ansx) <= EPS && (x[3] - ansx)*(x[4] - ansx) <= EPS ) {
                        count++;
                    }
                }
            } else {
                a = y[j]-y[0];  b = x[0]-x[j];
                p = x[0]*y[j]-x[j]*y[0];
                //(x3,y3)(x4,y4)を結ぶcx+dy=q の係数
                c = y[3]-y[4];  d = x[4]-x[3];
                q = x[4]*y[3]-x[3]*y[4];
                //係数についての行列式
                det = a*d-c*b;
                //det=0で解は存在しない(この問題については２線分は同一直線上にないから
                if(fabs(det) > EPS){
                    ansx = (d*p - b*q)/det;
                    if((x[j] - ansx)*(x[0] - ansx) <= EPS && (x[3] - ansx)*(x[4] - ansx) <= EPS ) {
                        count++;
                    }
                }
            }
        }
        if(count == 1) cout << "OK" << endl;
        else cout << "NG" << endl;
    }
}

C++: #include <iostream>
#include <string>
#include <vector>
#include <cmath>
using namespace std;

int crs(int x1, int y1, int x2, int y2) {
    return (0 < x1 * y2 - y1 * x2 ? 1 : -1);
}

int main() {
    int n,xp1,yp1,xp2,yp2,xp3,yp3,xk,yk,xs,ys;
    cin >> n;
    for (int i=0; i<n; ++i) {
        cin>>xp1>>yp1>>xp2>>yp2>>xp3>>yp3>>xk>>yk>>xs>>ys;
        int t1 = 0;
        t1 += crs(xp2 - xp1, yp2 - yp1, xk - xp1, yk - yp1);
        t1 += crs(xp3 - xp2, yp3 - yp2, xk - xp2, yk - yp2);
        t1 += crs(xp1 - xp3, yp1 - yp3, xk - xp3, yk - yp3);
        int t2 = 0;
        t2 += crs(xp2 - xp1, yp2 - yp1, xs - xp1, ys - yp1);
        t2 += crs(xp3 - xp2, yp3 - yp2, xs - xp2, ys - yp2);
        t2 += crs(xp1 - xp3, yp1 - yp3, xs - xp3, ys - yp3);
        if ((abs(t1) == 3 && abs(t2) != 3) ||
            (abs(t1) != 3 && abs(t2) == 3)) {
            cout << "OK" << endl;
        } else {
            cout << "NG" << endl;
        }
    }
    return 0;
}

C++: #include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
#include <math.h>
#include <algorithm>
using namespace std;
#define INF 0x7FFFFFFF
const double EPS = 1e-10;


inline bool eq(double a, double b) { return fabs(b - a) < EPS;}

struct p_t{
  double x;
  double y;
  double norm() { return x * x + y * y; }
  double abs() { return sqrt(norm()); }
};
struct l_t{
	p_t a, b;
};

double cross(p_t p,p_t q);
p_t line(p_t p,p_t q);

bool asc(p_t left,p_t right) {
    return left.x == right.x ? left.y < right.y : left.x < right.x;
}
int Crosspoint(l_t l,l_t m);

int main(){
  int n;
  cin>>n;
  for(int t=0;t<n;t++){
    p_t p,q,r,k,s;
    cin>>p.x>>p.y>>q.x>>q.y>>r.x>>r.y>>k.x>>k.y>>s.x>>s.y;
    l_t pq,qr,rp,ks;
    pq.a=p;
    pq.b=q;
    qr.a=q;
    qr.b=r;
    rp.a=r;
    rp.b=p;
    ks.a=k;
    ks.b=s;
    int ans=0;
    ans+=(Crosspoint(pq,ks)&&Crosspoint(ks,pq));
    ans+=(Crosspoint(qr,ks)&&Crosspoint(ks,pq));
    ans+=(Crosspoint(rp,ks)&&Crosspoint(ks,pq));
    if(ans==1){
      cout<<"OK"<<endl;
    }
    else{
      cout<<"NG"<<endl;
    }
  }
}


p_t line(p_t p,p_t q){
  p_t z;
  z.x=q.x-p.x;
  z.y=q.y-p.y;
  return z;
}


double cross(p_t p,p_t q){
  return p.x*q.y-p.y*q.x;
}

int Crosspoint(l_t l,l_t m){
  p_t aa,bb,cc,dd;
  aa.x=l.b.x-l.a.x;
  aa.y=l.b.y-l.a.y;
  bb.x=m.b.x-m.a.x;
  bb.y=m.b.y-m.a.y;
  cc=aa;
  dd.x=l.b.x-m.a.x;
  dd.y=l.b.y-m.a.y;
	double A = cross(aa,bb);
	double B = cross(cc,dd);
	//if (abs(A) < EPS && abs(B) < EPS) return 0;
  if(B/A>0&&B/A<1) return 1;
  return 0;
}

C++: #include <cmath>
#include <iomanip>
#include <iostream>
#include <vector>


#define EPSILON 1e-9


class vector_t {
public:
  double x;
  double y;
  double z;

public:
  vector_t(double x = 0, double y = 0, double z = 0) : x(x), y(y), z(z) {};

public:
  double operator*(const vector_t& v) const {
    return x * v.x + y * v.y + z * v.z;
  };

  vector_t operator^(const vector_t& v) const {
    return vector_t(y * v.z - z * v.y,
                    z * v.x - x * v.z,
                    x * v.y - y * v.x);
  };

public:
  double length() const {
    return sqrt(*this * *this);
  };
};


class point_t {
public:
  double x;
  double y;
  double z;
  double w;

public:
  point_t(double x = 0, double y = 0, double z = 0, double w = 1) : x(x), y(y), z(z), w(w) {};
  
public:
  vector_t operator-(const point_t& p) const {
    return vector_t(x - p.x, y - p.y, z - p.z);
  };
};


class point_triangle_intersect : public std::unary_function<point_t, bool> {
public:
  point_triangle_intersect(const point_t& p1,
                           const point_t& p2,
                           const point_t& p3) :
    p1_(p1), p2_(p2), p3_(p3), s_(((p2 - p1) ^ (p3 - p1)).z)
  {
  };
 
public:
  bool operator()(const point_t& p) const {
    double u = ((p1_ - p3_) ^ (p - p3_)).z / s_;
    double v = ((p2_ - p1_) ^ (p - p1_)).z / s_;

    return (u >= 0 && v >= 0 && u + v <= 1.0 + EPSILON);
  };
 
private:
  point_t p1_;
  point_t p2_;
  point_t p3_;

  double s_;
};


int main(int argc, char** argv)
{
  int n;

  std::cin >> n;

  for (int i = 0; i < n; i ++) {
    point_t p1, p2, p3, k, s;

    std::cin >> p1.x >> p1.y >> p2.x >> p2.y >> p3.x >> p3.y;
    std::cin >> k .x >> k .y >> s .x >> s .y;

    if (point_triangle_intersect(p1, p2, p3)(k) ^
        point_triangle_intersect(p1, p2, p3)(s)) {

      std::cout << "OK" << std::endl;
    }
    else {
      std::cout << "NG" << std::endl;
    }
  }

  return 0;
}