Problem:
三角形と円

平面上にある三角形と円の位置関係を判定するプログラムを作成してください。対象となる図形はいずれも境界を含むものとします。
三角形は 3 頂点の位置が与えられ、円は中心の位置と半径が与えられます。位置は直交座標系による２つの整数の組によって与えられます。半径も整数で与えられます。

Input

複数のデータセットの並びが入力として与えられます。入力の終わりはゼロふたつの行で示されます。
各データセットは以下の形式で与えられます。

x1 y1
x2 y2
x3 y3
xc yc
r

１行目から３行目に、三角形の第 i の頂点座標 xi, yi が与えられます。４行目に円の中心の座標 xc, yc、５行目に円の半径 r が与えられます。与えられる入力はすべて、1 以上 10,000 以下の整数とします。

データセットの数は 100 を超えません。

Output

入力データセットごとに以下の形式で判定結果を１行に出力します。

円が三角形に含まれる場合 a

三角形が円に含まれる場合 b

それ以外の場合で、共通部分がある場合には c

共通部分がない場合には d

Sample Input

1 1
3 1
3 3
3 2
3
3 12
9 3
11 12
8 7
5
15 3
17 7
22 5
7 6
4
6 11
8 2
16 9
10 8
2
0 0

Output for the Sample Input

b
c
d
a

Solution in JAVA (judge verdict: Accepted)

import java.awt.geom.Line2D;
import java.io.IOException;

public class Main {
	/**
	 * @param args
	 */
	static class Line extends Line2D.Double {
		public Line(int[] p1, int[] p2) {
			super(p1[0], p1[1], p2[0], p2[1]);
		}
	}

	static class Shape {
		public	int	x = 0;
		public	int	y = 0;
		public	int	r = 0;

		public Shape(int x, int y) {
			this.x = x;
			this.y = y;
		}

		public Shape(int x, int y, int r) {
			this.x = x;
			this.y = y;
			this.r = r;
		}
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[][]	d = null;

		while((d = inp()) != null) {
			solve(d);
		}
	}

	private static void solve(int[][] d) {
		{
			int	rr = (d[3][2]*d[3][2]);
			int	d0 = distPow(d[3], d[0]);
			int	d1 = distPow(d[3], d[1]);
			int	d2 = distPow(d[3], d[2]);

			if (d0 <= rr && d1 <= rr && d2 <= rr) {
				System.out.println("b");
				return;
			}
		}

		{
			int		n1 = crossSign(d[0], d[1], d[3]);
			int		n2 = crossSign(d[1], d[2], d[3]);
			int		n3 = crossSign(d[2], d[0], d[3]);
			Line	l1 = new Line(d[0], d[1]);
			Line	l2 = new Line(d[1], d[2]);
			Line	l3 = new Line(d[2], d[0]);
			double	dr = (double)d[3][2];
			double	s1 = l1.ptSegDist(d[3][0], d[3][1]);
			double	s2 = l2.ptSegDist(d[3][0], d[3][1]);
			double	s3 = l3.ptSegDist(d[3][0], d[3][1]);

			if ((n1 == n2) && (n2 == n3)) {
				if (s1 >= dr && s2 >= dr && s3 >= dr) {
					System.out.println("a");
				} else {
					System.out.println("c");
				}
			} else {
				if (s1 > dr && s2 > dr && s3 > dr) {
					System.out.println("d");
				} else {
					System.out.println("c");
				}
			}
		}
	}

	private static int distPow(int[] p1, int[] p2) {
		return (p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1]);
	}

	private static int crossSign(int[] p1, int[] p2, int[] p3) {
		int[]	vab = { p2[0]-p1[0], p2[1]-p1[1] };
		int[]	vap = { p3[0]-p1[0], p3[1]-p1[1] };
		int		sgn = cross(vab, vap);
		return (sgn==0)?0:((sgn>0)?1:-1);
	}

	private static int cross(int[] va, int[] vb) {
		return va[0]*vb[1]-va[1]*vb[0];   // x1*x2 + y1*y2
	}

	private static int[][] inp() {
		int[][]	d = new int[4][];

		for (int i = 0; i < 4; i++) {
			if (i < 3) {
				int[]	p = { parseNum(), parseNum() };
				if (p[0] == 0 && p[1] == 0) return null;
				d[i] = p;
			} else {
				int[]	p = { parseNum(), parseNum(), parseNum() };
				d[i] = p;
			}
		}

		return d;
	}

	private static int parseNum() {
		try {
			int	buf = 0;
			int	num = 0;
			int	mns = 0;
			int	skp = 1;

			// -,0〜9以外は読み飛ばす
			while (true) {
				buf = System.in.read();
				if (buf == '-') {
					mns = 1;
					skp = 0;
				} else if (buf >= '0' && buf <= '9') {
					num = num * 10 + (buf - '0');
					skp = 0;
				} else if ((skp == 0 || buf == -1) && buf != '.') {
					return (mns == 0)?num:num*(-1);
				}
			}
		} catch (IOException e) {}
		return -1;
	}
}