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++: #define _USE_MATH_DEFINES
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<string>
#include<vector>
#include<list>
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<cstring>
#include<stack>
using namespace std;
#define EPS 1e-8
#define INF 1000000
  
struct Point{
    double x,y;
    Point(){}
    Point(double _x,double _y){
        x=_x; y=_y;
    }
    Point operator +(const Point p)const{
        return Point(x+p.x,y+p.y);
    }
    Point operator -(const Point p)const{
        return Point(x-p.x,y-p.y);
    }
    Point operator *(const double d)const{
        return Point(x*d,y*d);
    }
    bool operator <(const Point &p)const{
        if(x==p.x) return y<p.y;
        return x<p.x;
    }
    bool operator ==(const Point &p)const{
        return abs(x-p.x)<EPS && abs(y-p.y)<EPS;
    }
    double norm(){
        return x*x+y*y;
    }
    bool input(){
        if(cin>>x>>y) return true;
        return false;
    }
};
 
struct Line{
    Point a,b;
    Line(){}
    Line(Point _a,Point _b){
        a=_a; b=_b;
    }
    bool input(){
        if(a.input() && b.input()) return true;
        return false;
    }
};
 
struct Circle{
    Point c;
    double r;
    Circle(){}
    Circle(Point _c,double _r){
        c=_c; r=_r;
    }
};
 
typedef Point Vector;
typedef vector<Point> Polygon;
typedef Line Segment;
 
double dot(Point p,Point q){
    return p.x*q.x+p.y*q.y;
}
 
double cross(Point p,Point q){
    return p.x*q.y-q.x*p.y;
}
 
int ccw(Point a,Point b,Point c){ 
    Vector v1 = b-a;
    Vector v2 = c-a;
    if(cross(v1,v2)>EPS) return +1; 
    if(cross(v1,v2)<-EPS) return -1; 
    if(dot(v1,v2)<-EPS) return +2; 
    if(v2.norm()-v1.norm()>EPS) return -2; 
    return 0; 
}
 
Point project(Segment s,Point p){
    Vector v1 = s.b-s.a;
    Vector v2 = p-s.a;
    double r = dot(v1,v2)/v1.norm();
    return s.a+v1*r;
}
 
Point reflect(Segment s,Point p){
    return p+(project(s,p)-p)*2.0;
}
 
bool intersect_ll(Line l,Line m){
    return ccw(l.a,l.b,m.a)*ccw(l.a,l.b,m.b)<=0 && ccw(m.a,m.b,l.a)*ccw(m.a,m.b,l.b)<=0;
}
 
bool crosspoint_ss(Segment s,Segment t,Point &p){
    Vector a1,a2,b1,b2;
    a1 = s.b-s.a; a2 = t.b-t.a;
    b1 = t.a-s.a; b2 = s.a-t.b;
    double s1,s2;
    s1 = cross(a1,b1)/2; s2 = cross(a1,b2)/2;
    if(s1+s2<EPS) return false; 
    p = Point(t.a.x+a2.x*s1/(s1+s2),t.a.y+a2.y*s1/(s1+s2));
    return true;
}
 
int crosspoint_ll(Line l,Line m,Point &p){
    if(intersect_ll(l,m)==false) return 0; 
    if(crosspoint_ss(l,m,p)==true) return 1;
    return -1; 
}
 
int crosspoint_cc(Circle c1,Circle c2,Point &p1,Point &p2){
    double d,a,t;
    d = sqrt((c2.c-c1.c).norm());
    if(abs(c1.c.x-c2.c.x)<EPS && abs(c1.c.y-c2.c.y)<EPS && abs(c1.r-c2.r)<EPS)
        return -1; 
    if(d<abs(c1.r-c2.r) || c1.r+c2.r<d) return 0; 
    a = acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2*c1.r*d));
    t = atan2(c2.c.y-c1.c.y,c2.c.x-c1.c.x);
    p1 = Point(c1.c.x+c1.r*cos(t+a),c1.c.y+c1.r*sin(t+a));
    p2 = Point(c1.c.x+c1.r*cos(t-a),c1.c.y+c1.r*sin(t-a));
    if(abs(p1.x-p2.x)<EPS && abs(p1.y-p2.y)<EPS) return 1; 
    return 2; 
}
 
int contain_gp(Polygon g,Point p){
    Line l = Line(p,Point(INF,p.y));
    int cnt = 0, n = g.size();
    for(int i=0;i<n;i++){
        Vector a = g[i]-p;
        Vector b = g[(i+1)%n]-p;
        if(ccw(g[i],g[(i+1)%n],p)==0) return 1; 
        if(a.y>b.y) swap(a,b);
        if(a.y<=EPS && EPS<b.y && cross(a,b)>EPS) cnt++;
    }
    if((cnt&1)==1) return 2; 
    return 0; 
}
 
Polygon andrewScan(Polygon s){
    if(s.size()<=2) return s;
    sort(s.begin(),s.end());
    Polygon g;
    for(int i=0;i<s.size();i++){
        for(int n=g.size(); n>=2 && ccw(g[n-2],g[n-1],s[i])!=-1; n--){
            g.pop_back();
        }
        g.push_back(s[i]);
    }
    int upper_n = g.size();
    for(int i=s.size()-2;i>=0;i--){
        for(int n=g.size(); n>upper_n && ccw(g[n-2],g[n-1],s[i])!=-1; n--){
            g.pop_back();
        }
        g.push_back(s[i]);
    }
    reverse(g.begin(),g.end());
    g.pop_back();
    return g;
}

int main(){
	Polygon g(3);
	Point k, s;
	int N;
	
	cin >> N;
	for(int ds = 0; ds < N; ds++){
		for(int i = 0; i < 3; i++) g[i].input();
		k.input(); s.input();
		if( contain_gp(g, s) != contain_gp(g, k) ) puts("OK");
		else puts("NG");
	}
	return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()

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

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

int main() {
  int n;
  cin >> n;
  while(n--) {
    int xp1,yp1,xp2,yp2,xp3,yp3,xk,yk,xs,ys;
    cin >> xp1 >> yp1 >> xp2 >> yp3 >> xk >> yk >> xs >> ys;
    P p1(xp1,yp1), p2(xp2,yp2), p3(xp3,yp3);
    L l[3];
    l[0] = L(p1,p2);
    l[1] = L(p2,p3);
    l[2] = L(p3,p1);
    P pk(xk,yk), ps(xs,ys);
    L ll(pk,ps);
    int c = 0;
    REP(i,3) {
      if (intersectSS(l[i],ll))
        c++;
    }
    if (c == 1) cout << "OK";
    else cout << "NG";
    cout << endl;
  }
}