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 <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <complex>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <iostream>
using namespace std;
typedef pair<int,int> P;
typedef long double ld;
typedef vector<int> vi;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define INF 2000000000
#define LINF 1000000000000000ll
#define sz(x) ((int)(x).size())
#define fi first
#define sec second
#define SORT(x) sort((x).begin(),(x).end())
#define all(x) (x).begin(),(x).end()
#define EQ(a,b) (abs((a)-(b))<eps)
bool isin(int a,int b,int c,int d,int p,int q)
{
	//printf("%d %d %d %d %d %d\n",a,b,c,d,p,q);
	ld s,t;
	ld A=a,B=b,C=c,D=d,P=p,Q=q;
	if(b==0)
	{
		t=Q/D;
		s=P/A-(C*Q)/(A*D);
		//cout << s << ' ' << t << endl;
		if(s>0&&t>0&&s+t<1)return true;
		else return false;
	}
	if(a==0)
	{
		t=P/C;
		s=Q/B-(D*Q)/(B*C);
		//cout << s << ' ' << t << endl;
		if(s>0&&t>0&&s+t<1)return true;
		else return false;
	}
	t=(P*B-A*Q)/(B*C-A*D);
	s=(P-C*t)/A;
	//cout << s << ' ' << t << endl;
	if(s>0&&t>0&&s+t<1)return true;
	else return false;
}
int main()
{
	int Q;
	scanf("%d",&Q);
	int x1,x2,x3,y1,y2,y3,xk,yk,xs,ys;
	for(int i=0;i<Q;i++)
	{
		scanf("%d %d %d %d %d %d %d %d %d %d",&x1,&y1,&x2,&y2,&x3,&y3,&xk,&yk,&xs,&ys);
		int a,b,c,d,p,q,r,s;
		a=x2-x1;
		b=y2-y1;
		c=x3-x1;
		d=y3-y1;
		p=xk-x1;
		q=yk-y1;
		r=xs-x1;
		s=ys-y1;
		bool orihime = isin(a,b,c,d,p,q);
		bool kengyu = isin(a,b,c,d,r,s);
		if(kengyu!=orihime)cout << "OK" << endl;
		else cout << "NO" << 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;
}