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>

using namespace std;

struct Point {
	double x, y;
};

bool 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);
		
		if (flag0y != flag1y) {
			if ( (flag0x == 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;
}

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), flag2 = PointInTri(tri, p2);
		if ( (flag1 && !flag2) || (!flag1 && flag2) ) cout << "OK" << endl;
		else cout << "NG" << endl;
	}
	
	return 0;
}

C++: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<sstream>
#include<utility>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
#define EPS 1e-10

double add(double a,double b)
{
	if(abs(a+b)<EPS*(abs(a)+abs(b)))return 0;
	return a+b;
}
typedef struct Vec{
	double x,y;
	Vec(){}
	Vec( double x,double y):x(x),y(y){}
	Vec operator +(Vec v){return Vec(add(x,v.x),add(y,v.y));}
	Vec operator -(Vec v){return Vec(add(x,-v.x),add(y,-v.y));}
	Vec operator *(double d){return Vec(x*d,y*d);}
	double dot(Vec v){return add(x*v.x,y*v.y);}
	double det(Vec v){return add(x*v.y,-y*v.x);}
}V;


bool on_seg(Vec p1,Vec p2,Vec q)
{
	return (p1-q).det(p2-q)==0&&(p1-q).dot(p2-q)<=0;
}

Vec intersection(Vec p1,Vec p2,Vec q1,Vec q2)
{
	return p1+(p2-p1)*((q2-q1).det(q1-p1)/(q2-q1).det(p2-p1));
}

Vec A,B;
int N,p=1,c=0;
Vec pos[3];

void check(Vec f,Vec e)
{
	if((B-A).det(e-f)!=0)
	{
		Vec r=intersection(A,B,f,e);
		if(on_seg(A,B,r)&&on_seg(f,e,r))
		{
			c++;
		}
	}
}

int main()
{
	int N;
	scanf("%d",&N);
	for(;N--;)
	{
		c=0;
		for(int i=0;i<3;i++)
			scanf("%lf%lf",&pos[i].x,&pos[i].y);
		scanf("%lf%lf",&A.x,&A.y);
		scanf("%lf%lf",&B.x,&B.y);
		for(int i=0;i<3;i++)
			check(pos[i],pos[(i+1)%3]);
		puts(c==1?"OK":"NG");
	}
}

C++: #include <iostream>
#include <stdio.h>

using namespace std;

int hantei(double ax,double ay,double bx,double by,double cx,double cy,double dx,double dy) {
	double x,y,m,n,d;
	if (dx-cx!=0) m=(dy-cy)/(dx-cx);
	if (bx-ax!=0) n=(by-ay)/(bx-ax);
	if (ay==by) {
		if (cx==dx && ((cx>ax && cx<bx) || (cx>bx && cx<ax)) && ((cy<ay && dy>ay) || (dy<ay && cy>ay))) return 1;
        x=(ay-cy+m*cx)/m;
        if ((x>cx && x<dx) || (x>dx && x<cx)) return 1;
		return 0;
	}
	if (ax==bx) {
        if (cy==dy && ((cy>ay && cy<by) || (cy>by && cy<ay)) && ((cx<ax && dx>ax) || (dx<ax && cx>ax))) return 1;
        y=cy+m*(ax-cx);
		if ((y>ay && y<by) || (y>by && y<ay)) return 1;
		return 0;
	}
	if (cy==dy) { x=(cy-ay+n*ax)/n;	if ((x>cx && x<dx) || (x>dx && x<cx)) return 1; else return 0; }
	if (cx==dx) { y=ay+n*(cx-ax); if ((y>cy && y<dy) || (y>dy && y<cy)) return 1; else return 0;}
	if (m==n) return 0;
    d=(ay-cy+m*cx-n*ax)/(m-n);
	if ((d>cx && d<dx) || (d>dx && d<cx)) return 1;
	return 0;
}

int main() {
	int n,f;
	double xp1,yp1,xp2,yp2,xp3,yp3,xk,yk,xs,ys;
	cin >> n;
	for (;n>0;n--) {
		cin >> xp1 >> yp1 >> xp2 >> yp2 >> xp3 >> yp3 >> xk >> yk >> xs >> ys;
        f=hantei(xp1,yp1,xp2,yp2,xk,yk,xs,ys)+hantei(xp2,yp2,xp3,yp3,xk,yk,xs,ys)+hantei(xp1,yp1,xp3,yp3,xk,yk,xs,ys);
		if (f==1) cout << "OK"; else cout << "NG";
		cout << endl;
	}
return 0;
	}

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

typedef pair<double,double>P;
#define X first
#define Y second

P sub(P a,P b){
	return P(a.X-b.X,a.Y-b.Y);
}

int chk(P a,P b,P c,P p){
	P ab=sub(b,a);
	P bp=sub(p,b);
	P bc=sub(c,b);
	P cp=sub(p,c);
	P ca=sub(a,c);
	P ap=sub(p,a);
	double c1 = ab.X * bp.Y - ab.Y * bp.X;
	double c2 = bc.X * cp.Y - bc.Y * cp.X;
	double c3 = ca.X * ap.Y - ca.Y * ap.X;
	if( ( c1 > 0 && c2 > 0 && c3 > 0 ) || ( c1 < 0 && c2 < 0 && c3 < 0 ) ) {
		//三角形の内側に点がある
		return 1;
	}
	return 0;
}

int main(){
	
	int n;cin>>n;
	while(n--){
		P a,b,c,d,e;
		cin>>a.X>>a.Y>>b.X>>b.Y>>c.X>>c.Y>>d.X>>d.Y>>e.X>>e.Y;
		if(chk(a,b,c,d)+chk(a,b,c,e)==1)cout<<"OK\n";
		else cout<<"NG\n";
		
	}
	return 0;
}

C++: #include<bits/stdc++.h>
#define f first
#define s second
#define mp make_pair
#define inf 100000000
#define eps (1e-11)
#define equals(a,b) (fabs((a)-(b))<eps)
using namespace std;

class Point{
public:
  double x,y;
  Point(double x=0,double y=0):x(x),y(y){}

  Point operator+(Point p){ return Point(x+p.x,y+p.y);}
  Point operator-(Point p){ return Point(x-p.x,y-p.y);}
  Point operator*(double k){ return Point(x*k,y*k);}
  Point operator/(double k){ return Point(x/k,y/k);}
  bool operator<(Point p)const{ return (x!=p.x ? x<p.x : y<p.y);}
  bool operator==(Point p)const{ return fabs(x-p.x)<eps && fabs(y-p.y)<eps;}

  double abs(){ return sqrt(norm());}
  double norm(){ return (x*x+y*y);}
};
typedef Point Vector;
typedef vector<Point> Polygon;

class Segment{
public:
  Point p1,p2;
  Segment(Point p1,Point p2):p1(p1),p2(p2){}
};
double norm(Vector a){ return (a.x*a.x+a.y*a.y);}
double abs(Vector a){ return sqrt(norm(a));}
double dot(Vector a,Vector b){ return (a.x*b.x+a.y*b.y);}
double cross(Vector a,Vector b){ return (a.x*b.y-a.y*b.x);}

static const int COUNTER_CLOCKWISE=1;
static const int CLOCKWISE=-1;
static const int ONLINE_BACK=2;
static const int ONLINE_FRONT=-2;
static const int ON_SEGMENT=0;

int ccw(Point p0,Point p1,Point p2){
  Vector a=p1-p0;
  Vector b=p2-p0;
  if(cross(a,b)>eps)return COUNTER_CLOCKWISE;
  if(cross(a,b)<-eps)return CLOCKWISE;
  if(dot(a,b)<-eps)return ONLINE_BACK;
  if(a.norm()<b.norm())return ONLINE_FRONT;
  return ON_SEGMENT;
}

bool intersect(Point p1,Point p2,Point p3,Point p4){
  return (ccw(p1,p2,p3)*ccw(p1,p2,p4)<=0 &&
          ccw(p3,p4,p1)*ccw(p3,p4,p2)<=0);
}

bool intersect(Segment s1,Segment s2){
  return intersect(s1.p1,s1.p2,s2.p1,s2.p2);
}

int main()
{
  int n;
  int a,b,c,d,e,f,sx,sy,gx,gy;
  Point p[3];

  cin>>n;
  for(int i=0;i<n;i++){
    cin>>p[0].x>>p[0].y>>p[1].x>>p[1].y>>p[2].x>>p[2].y;
    cin>>sx>>sy>>gx>>gy;
    Segment s(Point(sx,sy),Point(gx,gy));
    int c=0;
    for(int i=0;i<3;i++){
      if(intersect(s,Segment(p[i],p[(i+1)%3])))c++;
    }
    if(c==1)cout<<"OK"<<endl;
    else cout<<"NG"<<endl;
  }
  return 0;
}