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 <vector>
#include <cmath>
 
using namespace std;

typedef double D;
D EPS = 1e-10;

struct Point {
	D x, y;
	Point() {}
	Point (D _x, D _y) : x(_x), y(_y) {}
};
typedef Point Vector;	// typedef テ」ツ?ァテ」ツδ凖」ツつッテ」ツδ暗」ツδォテ」ツ?ォテ・ツッツセテ・ツソツ?

// operator
Point operator + (const Point& a, const Point& b) { return Point(a.x+b.x, a.y+b.y); }
Point operator - (const Point& a, const Point& b) { return Point(a.x-b.x, a.y-b.y); }
Point operator * (const Point& a, const Point& b) { return Point(a.x*b.x, a.y*b.y); }
Point operator / (const Point& a, const Point& b) { return Point(a.x/b.x, a.y/b.y); }
bool operator < (const Point& a, const Point& b) { return a.x != b.x ? a.x < b.x : a.y < b.y; }
bool operator > (const Point& a, const Point& b) { return b.x != a.x ? b.x < a.x : b.y < a.y; }
bool operator == (const Point& a, const Point& b) { return fabs(a.x-b.x)<EPS && fabs(a.y-b.y)<EPS; }

// テ・ツ淞コテヲツ慊ャテァツ堋?」ツ?ェテゥツ鳴「テヲツ閉ー
D norm(const Point& a) { return sqrt(a.x*a.x + a.y*a.y); }
D dot(const Vector& a, const Vector& b) { return a.x*b.x + a.y*b.y; }	// テ・ツ??ァツゥツ?
D cross(const Vector& a, const Vector& b) { return a.x*b.y - a.y*b.x; }	// テ・ツ、ツ姪ァツゥツ?
D dist(const Point& a, const Point& b) { return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); } // ティツキツ敕ゥツ崢「
bool isVertical(const Vector& a, const Vector& b) { return fabs(dot(a,b))<EPS; }	// テ・ツ楪づァツ崢エテ・ツ按、テ・ツョツ?
bool isParrallel(const Vector& a, const Vector& b) { return fabs(cross(a,b))<EPS; } // テ・ツケツウティツ。ツ古・ツ按、テ・ツョツ?

struct Line {
	Point s, e;
	Line (Point _s, Point _e) {
		s = _s; e = _e;
	}
};

bool PointOnLine(const Point& p, const Line& l) {
	int minx = min(l.s.x, l.e.x), maxx = max(l.s.x, l.e.x);
	int miny = min(l.s.y, l.e.y), maxy = max(l.s.y, l.e.y);
	if ( !(minx <= p.x && p.x <= maxx && miny <= p.y && p.y <= maxy) ) return false;
	Vector v1 = p - l.s, v2 = l.e - l.s;
	return isParrallel(v1, v2);
}

enum { IN, ON, OUT };
int PointInTri(const vector<Point>& tri, const Point& p) {
    int cnt = 0;
    for (int i=1; i<4; i++) {
        Point p0 = tri[i-1], p1 = tri[i%3];
        bool flag0x = (p.x <= p0.x), flag0y = (p.y <= p0.y);
        bool flag1x = (p.x <= p1.x), flag1y = (p.y <= p1.y);
        
        Line p0top1(p0, p1);
        if (PointOnLine(p, p0top1)) return ON;
         
        if (flag0y != flag1y) {
            if ( flag1x && flag0x) {
                cnt += flag0y ? -1 : 1;
            } else if (p.x <= ( p0.x+(p1.x-p0.x)*(p.y-p0.y)/(p1.y-p0.y) ) ) {
                cnt += flag0y ? -1 : 1;
            }
        }
    }
    return cnt!=0 ? IN : OUT;
}
 
int main() {
    int n; cin >> n;
     
    vector<Point> tri(3);
    for (int i=0; i<n; i++) {
        cin >> tri[0].x >> tri[0].y >> tri[1].x >> tri[1].y >> tri[2].x >> tri[2].y;
        Point p1; cin >> p1.x >> p1.y;
        Point p2; cin >> p2.x >> p2.y;
        bool flag1 = (PointInTri(tri, p1) == IN), flag2 = (PointInTri(tri, p2) == IN);
        if ( flag1 != flag2 ) cout << "OK" << endl;
        else cout << "NG" << endl;
    }
     
    return 0;
}

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

struct point{
	double x;
	double y;
};

int ccw(point p0, point p1, point p2){
	double dx1 = p1.x - p0.x, dy1 = p1.y - p0.y;
	double dx2 = p2.x - p0.x, dy2 = p2.y - p0.y;
	if(dx1 * dy2 > dx2 * dy1){
		return 1;
	}else if(dx1 * dy2 > dx2 * dy1){
		return -1;
	}
	return 0;
}

bool in_t(point p0, point p1, point p2, point p3){
	if((ccw(p0, p1, p2) != ccw(p0, p1, p3)
		&& (ccw(p0, p2, p1) != -ccw(p0, p2, p3))))
		return true;
	else return false;
}


int main(){
	int n;
	cin >> n;
	for(int i = 0; i < n; i++){
		point p1, p2, p3;
		point pk, ps;
		cin >> p1.x >> p1.y >> p2.x >> p2.y
			>> p3.x >> p3.y >> pk.x >> pk.y >>  ps.x >> ps.y;
		if((in_t(pk, p1, p2, p3) && !in_t(ps, p1, p2, p3)) ||
			(!in_t(pk, p1, p2, p3) && in_t(ps, p1, p2, p3)))
			cout << "OK" << endl;
		else cout << "NG" << endl;
	}
	return 0;
}

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

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

int point_contain(segment* ps, point p, int n){
  int cnt=0;
  point q;
  q.x=q.y=2000000000;
  for(int i=0;i<n;i++)
	cnt+=is_intersected_ls(ps[i].a,ps[i].b,p,q);
  
  return cnt%2;
}

int main(void){
  int n;
  point p[3],k,s;
  segment seg[3];

  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;
    int cnt=0,l=0;
    for(int i=0;i<3;i++)
      for(int j=i+1;j<3;j++)
	if(i!=j){
	  seg[i].a=p[i];
	  seg[i].b=p[j];
	  l++;
	}
     

    if(point_contain(seg,k,l)!=point_contain(seg,s,l))cout << "OK" << endl;
    else cout << "NG" << endl;
    
  }

  return 0;
}