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 <bits/stdc++.h>

using namespace std;

const double EPS = 1e-8;
const double INF = 1e12;
typedef complex<double> P;
namespace std {
  bool operator < (const P& a, const P& b) {
      return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
    }
}
double cross(const P& a, const P& b) {
  return imag(conj(a)*b);
}
double dot(const P& a, const P& b) {
  return real(conj(a)*b);
}

typedef vector<P> G;

#define curr(P, i) P[i]
#define next(P, i) P[(i+1)%P.size()]
int contains(const G& g, const P& p) {
  bool in = false;
  for (int i = 0; i < g.size(); ++i) {
      P a = curr(g,i) - p, b = next(g,i) - p;
      if (imag(a) > imag(b)) swap(a, b);
      if (imag(a) <= 0 && 0 < imag(b))
        if (cross(a, b) < 0) in = !in;
      if (cross(a, b) == 0 && dot(a, b) <= 0) return true;
    }
  return in ? true : false;
}

int main(){
    int n;
    cin >> n;
    for(int q=0; q < n; q++){
        G g(3); P a, b;
        double xp1,yp1,xp2,yp2,xp3,yp3, xk, yk, xs, ys;
        cin >> xp1 >> yp1 >> xp2 >> yp2 >> xp3 >> yp3 >> xk >> yk >> xs >> ys;
        g[0] = P(xp1, yp1); g[1] = P(xp2, yp2); g[2] = P(xp3, yp3);
        a = P(xk, yk); b = P(xs, ys);
        cout << (contains(g, a) xor contains(g, b) ? "OK" : "NG") << endl;
    }
}

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

int cross(int a, int b, int c, int d) {
    return a * d - b * c;
}

int main() {
    int n;

    cin >> n;
    while (n--) {
        int xp[3], yp[3], x[2], y[2];
        int cp[2][3];

        for (int i = 0; i < 3; i++) {
            cin >> xp[i] >> yp[i];
        }   
        for (int i = 0; i < 2; i++) {
            cin >> x[i] >> y[i];
        }

        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < 3; j++) {
                int k = (j+1) % 3;
                cp[i][j] = cross(xp[k]-xp[j], yp[k]-yp[j], x[i]-xp[j], y[i]-yp[j]) > 0;
            }
        }
        bool judge = false;
        if (cp[0][0] == cp[0][1] && cp[0][0] == cp[0][2]) {
            if (cp[1][0] != cp[1][1] || cp[1][0] != cp[1][2]) {
                judge = true;
            }
        }
        else if (cp[1][0] == cp[1][1] && cp[1][0] == cp[1][2]) {
            judge = true;
        }
        cout << (judge? "OK": "NG") << endl;

    }
    return 0;
}

C++: #include <bits/stdc++.h>
  
using namespace std;
  
typedef double D;
typedef complex<D> P;
#define EPS (1e-10)
 
D dot(P a, P b)
{
    return real(conj(a) * b);
}
 
D cross(P a, P b)
{
    return imag(conj(a) * b);
} 
 
int ccw(P p0, P p1, P p2)
{
    P a = p1 - p0;
    P b = p2 - p0;
  
    if (cross(a,b) > EPS) return 1;
    if (cross(a,b) < -EPS) return -1;
    if (dot(a,b) < -EPS) return 2;
    if (norm(a) < norm(b)) return -2;
    return 0;
}
 
bool check(P p1, P p2, P p3, P p4)
{
    return (ccw(p1, p2, p3)*ccw(p1, p2, p4) <= 0 &&
	    ccw(p3, p4, p1)*ccw(p3, p4, p2) <= 0);
}
  
int main()
{
    int n;
    P P[3], T[2];
  
    scanf("%d", &n);
    while (n--) {
	for (int i = 0; i < 3; i++) {
	    scanf("%lf %lf", &P[i].real(), &P[i].imag());
	}
 
	for (int i = 0; i < 2; i++) {
	    scanf("%lf %lf", &T[i].real(), &T[i].imag());
	}
 
	int cnt = 0; 
	if (check(P[0], P[1], T[0], T[1])) {
	    cnt++;
	}   
	if (check(P[0], P[2], T[0], T[1])) {
	    cnt++;
	} 
	if (check(P[1], P[2], T[0], T[1])) {
	    cnt++;
	} 
	if (cnt % 2) {
	    puts("OK");
	} else {
	    puts("NG");
	}
    }
    return 0;
}

C++: #define _USE_MATH_DEFINES
#include <iostream>
#include <sstream>
#include <cmath>
#include <algorithm>
#include <queue>
#include <stack>
#include <limits>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <deque>

using namespace std;

typedef long long ll;
typedef pair<double,int> P;

static const double eps = 10e-6;

class intersect_triangle{
private:
	double dst[3];
	double orig[3], dir[3];
	double vert0[3],vert1[3],vert2[3];

	double dot(double v1[3],double v2[3]){
		return v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2];
	}
	void cross(double dest[3],double v1[3],double v2[3]){
		dest[0] = v1[1]*v2[2]-v1[2]*v2[1];
		dest[1] = v1[2]*v2[0]-v1[0]*v2[2];
		dest[2] = v1[0]*v2[1]-v1[1]*v2[0];
	}

	void sub(double dest[3],double v1[3], double v2[3]){
		dest[0] = v1[0]-v2[0];
		dest[1] = v1[1]-v2[1];
		dest[2] = v1[2]-v2[2];
	}
public:
	intersect_triangle(double xp1,double yp1,double xp2,double yp2,double xp3,double yp3,
		double xk,double yk){
		vert0[0] = xp1;
		vert0[1] = yp1;
		vert0[2] = 0;

		vert1[0] = xp2;
		vert1[1] = yp2;
		vert1[2] = 0;

		vert2[0] = xp3;
		vert2[1] = yp3;
		vert2[2] = 0;

		orig[0] = xk;
		orig[1] = yk;
		orig[2] = -1;

		dst[0] = xk;
		dst[1] = yk;
		dst[2] = 1;

		double len = sqrt(pow(dst[0]-orig[0],2.0)+pow(dst[1]-orig[1],2.0)+pow(dst[2]-orig[2],2.0));
		dir[0] = (dst[0]-orig[0])/len;
		dir[1] = (dst[1]-orig[1])/len;
		dir[2] = (dst[2]-orig[2])/len;
	}

	bool is_intersect(){
		double edge1[3],edge2[3],tvec[3],pvec[3],qvec[3];
		double det,inv_det,t=0,v=0,u=0;

		sub(edge1,vert1,vert0);
		sub(edge2,vert2,vert0);

		cross(pvec,dir,edge2);

		det=dot(edge1,pvec);

		if(det > -eps && det < eps) return false;

		inv_det = 1.0/det;

		sub(tvec,orig,vert0);

		u=dot(tvec,pvec)*inv_det;
		if(u < 0.0 || u > 1.0) return false;

		cross(qvec,tvec,edge1);

		v=dot(dir,qvec) * inv_det;
		if(v < 0.0 || u+v > 1.0) return false;

		t = dot(edge2,qvec) * inv_det;

		return true;

	}
};

int main(){
	int n;
	scanf("%d",&n);

	for(int i=0;i<n;i++){
		double xp1,yp1,xp2,yp2,xp3,yp3,xk,yk,xs,ys;
		scanf("%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
			&xp1,&yp1,&xp2,&yp2,&xp3,&yp3,&xk,&yk,&xs,&ys);
		intersect_triangle inter_t1(xp1,yp1,xp2,yp2,xp3,yp3,xk,yk);
		intersect_triangle inter_t2(xp1,yp1,xp2,yp2,xp3,yp3,xs,ys);
		printf("%s\n",(inter_t1.is_intersect() && inter_t2.is_intersect()) 
			|| (!inter_t1.is_intersect() && !inter_t2.is_intersect())
			? "NG" : "OK");
	}
}