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<cmath>
#include<algorithm>
#include<iostream>
#include<vector>
#include<climits>
#include<cfloat>
 
using namespace std;
 
double EPS = 1e-10;
 
double add(double a, double b){
  if(abs(a+b) < EPS * (abs(a)+abs(b)))return 0;
  return a+b;
}
 
struct point{
  double x, y;
  point(){}
  point(double x,double y) : x(x) , y(y){}
 
  point operator + (point p){
    return point(add(x,p.x), add(y,p.y));
  }
 
  point operator - (point p){
    return point(add(x,-p.x), add(y,-p.y));
  }
 
  point operator * (double d){
    return point(x*d,y*d);
  }
};
 
struct segment{
  point a,b;
};
 
double dot(point a, point b) {
  return (a.x * b.x + a.y * b.y);
}
 
double cross(point a, point b) {
  return (a.x * b.y - a.y * b.x);
}
 
int is_intersected_ls(point a1, point a2, point b1, point b2) {
  return ( cross(a2-a1, b1-a1) * cross(a2-a1, b2-a1) < EPS ) &&
         ( cross(b2-b1, a1-b1) * cross(b2-b1, a2-b1) < EPS );
}

 double vec_abs(point a){
  return sqrt(a.x*a.x+a.y*a.y);
}

int ccw(point p0, point p1, point p2){
  point a = p1 - p0;
  point 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(a.x*a.x+a.y*a.y<b.x*b.x+b.y*b.y)return -2;
  return 0;
}

int is_point_on_line(point a, point b, point c) {
  return (vec_abs(a-c) + vec_abs(c-b) < vec_abs(a-b) + EPS);
}

int inside(point p, point* ps, int n){
  segment t;
  t.a=t.b=p;
  t.b.x=DBL_MAX;
  ps[n]=ps[0];
  double ymx=-DBL_MAX,ymn=DBL_MAX;
  for(int i=0;i<n;i++){
    ymx=max(ymx,ps[i].y);
    ymn=min(ymn,ps[i].y);
  }
  if(t.a.y<=ymn||t.a.y>=ymx)return 0;

  double xmx=-DBL_MAX,xmn=DBL_MAX;
  for(int i=0;i<n;i++){
    xmx=max(xmx,ps[i].x);
    xmn=min(xmn,ps[i].x);
  }
  if(t.a.x<=xmn||t.a.x>=xmx)return 0;

  int cnt=0;
  for(int i=0;i<n;i++){
    if(is_intersected_ls(ps[i],ps[i+1],t.a,t.b))cnt++;
  }

  return cnt%2;
}

int main(void){
  int n;
  point p[4],k,s;
 
  cin >> n;
  while(n--){

    for(int i=0;i<3;i++)
      cin >> p[i].x >> p[i].y;
     
    cin >> k.x >> k.y >> s.x >> s.y;
    if(inside(k,p,3)!=inside(s,p,3))cout << "OK" << endl;
    else cout << "NG" << endl;
     
  }
 
  return 0;
}

C++: #define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#include <complex>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<int> vi;
typedef vector<vi> vvi;
#define all(c) (c).begin(), (c).end()
#define loop(i,a,b) for(int i=a; i<int(b); i++)
#define rep(i,b) loop(i,0,b)
#define each(e,c) for(auto& e:c)
#define iter(it,c) for(auto it=c.begin(); it!=c.end(); ++it)

ll const inf = 1<<28;
double const pi = acos(-1);

typedef complex<double> P;

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);
}

struct L : public vector<P> {
    L(const P &a, const P &b) {
        push_back(a); push_back(b);
    }
    L(){}
};

int ccw(P a, P b, P c) {
    b -= a; c -= a;
    if (cross(b, c) > 0)   return +1;       // counter clockwise
    if (cross(b, c) < 0)   return -1;       // clockwise
    if (dot(b, c) < 0)     return +2;       // c--a--b on line
    if (norm(b) < norm(c)) return -2;       // a--b--c on line
    return 0;
}

bool intersectSS(const L &s, const L &t) {
    return ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1]) <= 0 &&
        ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1]) <= 0;
}

P ps[4];
L l;

bool solve(){
    int c=0;
    rep(i,3){
        L m(ps[i],ps[i+1]);
        if(intersectSS(l,m))c++;
    }
    return c==1;
}

int main(){
    int n;cin>>n;
    rep(_,n){
        rep(i,3){
            double x,y;cin>>x>>y;
            ps[i]=P(x,y);
        }
        ps[3]=ps[0];
        double a,b,c,d;
        cin>>a>>b>>c>>d;
        l={P(a,b),P(c,d)};
        cout << (solve()?"OK":"NG")<<endl;
    }
}

C++: #include <cmath>
#include <complex>
#include <vector>
#include <cstdio>
using namespace std;


#define EPS 1e-7


typedef complex<double> point;
typedef vector<point> polygon;


bool contains(const polygon &plg, const point &pt){
	int cnt = 0;
	double y = imag(pt);

	for(int i = 1; i < plg.size(); ++i){
		double dyi = imag(plg[i]) - y;
		double dyj = y - imag(plg[i-1]);
		double tx = (dyi * real(plg[i-1]) + dyj * real(plg[i])) / (dyi + dyj);

		if(imag(plg[i]) >= y && imag(plg[i-1]) < y){
			if( tx < real(pt) ) ++cnt;
		}
		else if(imag(plg[i]) < y && imag(plg[i-1]) >= y){
			if( tx < real(pt) ) ++cnt;
		}
	}
	
	return (cnt % 2 != 0);
}


int main(){
	int n;
	int x, y;
	vector<point> tri(4);
	
	for(scanf("%d", &n); n--; ){
		for(int i = 0; i < 3; ++i){
			scanf("%d%d", &x, &y);
			tri[i] = point(x, y);
		}
		tri[3] = tri[0];

		scanf("%d%d", &x, &y);
		point pk(x, y);
		scanf("%d%d", &x, &y);
		point ps(x, y);
		
		if( contains(tri, pk) != contains(tri, ps) ){
			puts("OK");
		}
		else{
			puts("NG");
		}
	}
}

C++: #include <iostream>
#include <vector>
//#include <fstream>	// require freopen
#include <complex>

using namespace std;

typedef complex <double> P;

#define EPS (1e-10)
#define EQ(a,b) (abs((a)-(b)) < EPS)

// OÏ (cross product) : a~b = |a||b|sinÆ
double cross(P a, P b) {
  return (a.real() * b.imag() - a.imag() * b.real());
}

int main()
{
//	cut here before submit 
//	freopen ("testcase.altair6vega", "r", stdin );
	int n;
	int i, j;
	vector <bool> res;

	cin >> n;

	for (i = 0; i < n; ++i){
		double x1, y1, x2, y2, x3, y3;
	
		cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
		P a(x1, y1), b(x2, y2), c(x3, y3 );

		vector <P> p(2);
		for (j = 0; j < 2; ++j ){
			cin >> p[j].real() >> p[j].imag();
		} // end for

		vector <bool> in (2, false );

		for (j = 0; j < 2; ++j ){	
			if (  ( cross (p[j] - a, p[j] - b ) > 0. && cross (p[j] - b, p[j] - c ) > 0. && cross (p[j] - c , p[j] - a ) > 0. )
			||    ( cross (p[j] - a, p[j] - b ) < 0. && cross (p[j] - b, p[j] - c ) < 0. && cross (p[j] - c , p[j] - a ) < 0. ) ) {
				in[j] = true;
			}else{
				in[j] = false;
			} // end if
		} // end for
		if (in[0] ^ in[1] ){
			res.push_back (true );
		}else{
			res.push_back (false );
		} // end if
	} // end for

	for (i = 0; i < n; ++i){
		if (res[i] ){
			cout << "OK" << endl;
		}else{
			cout << "NG" << endl;
		} // end if
	} // end for
		
	return 0;
}