Problem:
宇宙船 UAZ アドバンス号

恒星歴 2005.11.5。あなたは宇宙船 UAZ アドバンス号の艦長として敵の宇宙船と交戦しようとしています。 幸い敵の宇宙船はまだこちらに気付かずに静止しています。また、すでに敵の宇宙座標は判明しており強力な直線のビームを放つ「フェザー砲」は発射準備を完了しています。あとは、発射命令を出すばかりです。

ところが、宇宙空間には、敵の設置したエネルギーバリアが存在しています。バリアは三角形をしており「フェザー砲」のビームをはね返してしまいます。また、ビームがバリアに当たれば敵に気付かれて逃げられてしまいます。事前に命中すると判定できなければ、発射命令は出せません。

そこで、UAZ アドバンス号、敵、バリアの位置の宇宙座標(3次元座標 x, y, z) を入力して、ビームがバリアをさけて敵に命中する場合は "HIT"、バリアに当たってしまう場合"MISS"と出力するプログラムを作成してください。

ただし、バリアはアドバンス号から 3 角形に見えるものだけが対象であり、線分につぶれて見えるものはないものとします。また、バリアは 3 角形の頂点を含む境界でも有効であり、ビームをはね返すものとします。また、敵がバリア内にいる場合は"MISS"と出力して下さい。

Input

入力データの形式は以下のとおりです：

1 行目は、UAZ アドバンス号の座標 (x, y, z) (整数、半角空白区切り)

2 行目は、敵の座標 (x, y, z) (整数、半角空白区切り)

3 行目は、バリアの頂点 1 の座標 (x, y, z) (整数、半角空白区切り)

4 行目は、バリアの頂点 2 の座標 (x, y, z ) (整数、半角空白区切り)

5 行目は、バリアの頂点 3 の座標 (x, y, z ) (整数、半角空白区切り)

Output

HIT または MISS と１行に出力してください。

Constraints

-100 ≤ x, y, z ≤ 100

UAZ アドバンス号と敵が同じ位置にいることはない。

Sample Input 1

-10 0 0
10 0 0
0 10 0
0 10 10
0 0 10

Output for the Sample Input 1

HIT

Sample Input 2

-10 6 6
10 6 6
0 10 0
0 10 10
0 0 10

Output for the Sample Input 2

MISS

Solution in C# (judge verdict: Accepted)

using System;

namespace AOJ {
    class _0115 {
        static int N = 3;

        static void Decomp(double[,] m) {
            double p;
            for (int k = 0; k < N; k++) {
                for(int i = k + 1; i < N; i++) {
                    p = m[i, k] / m[k, k];
                    for (int j = k + 1; j < N; j++)
                        m[i, j] -= p * m[k, j];
                    m[i, k] = p;
                }
            }
        }
        static void LUSolver(double[,] A, double[] b) {
            double sum;

            for (int i = 1; i < N; i++) {
                sum = 0;
                for (int j = 0; j <= i - 1; j++)
                    sum += A[i, j] * b[j];
                b[i] -= sum;
            }

            for(int i = N - 1; i >= 0; i--) {
                sum = 0.0;
                for (int j = i + 1; j <= N - 1; j++)
                    sum += A[i, j] * b[j];
                b[i] = (b[i] - sum) / A[i, i];
            }
        }
        static void MakeMUV(double[] u, double[] e, double[,] b, double[,] m, double[] v) {
            m[0, 0] = e[0] - u[0]; m[0, 1] = b[0, 0] - b[1, 0]; m[0, 2] = b[0, 0] - b[2, 0];
            m[1, 0] = e[1] - u[1]; m[1, 1] = b[0, 1] - b[1, 1]; m[1, 2] = b[0, 1] - b[2, 1];
            m[2, 0] = e[2] - u[2]; m[2, 1] = b[0, 2] - b[1, 2]; m[2, 2] = b[0, 2] - b[2, 2];
            v[0] = b[0, 0] - u[0];
            v[1] = b[0, 1] - u[1];
            v[2] = b[0, 2] - u[2];

            if (isZero(m[0, 0]))
                if (!isZero(m[1, 0]))
                    SwapRow(m, v, 0, 1);
                else if (!isZero(m[2, 0]))
                    SwapRow(m, v, 0, 2);
            if (isZero(m[1, 1]))
                if (!isZero(m[2, 1]))
                    SwapRow(m, v, 1, 2);
        }

        static void SwapRow(double[,] m, double[] v, int n1, int n2) {
            double tmp;
            for (int i = 0; i < N; i++) {
                tmp = m[n1, i];
                m[n1, i] = m[n2, i];
                m[n2, i] = tmp;
            }
            tmp = v[n1];
            v[n1] = v[n2];
            v[n2] = tmp;
        }
        static bool isZero(double x) {
            return (x >= 0 && x < double.Epsilon * 1e5);
        }

        public static void Main() {
            double[,] A = new double[N, N];
            double[] uaz = new double[N];
            double[] enm = new double[N];
            double[,] bs = new double[N, N];
            double[] b = new double[N];

            string[] strs = Console.ReadLine().Split();
            for (int i = 0; i < N; i++)
                uaz[i] = double.Parse(strs[i]);
            strs = Console.ReadLine().Split();
            for (int i = 0; i < N; i++)
                enm[i] = double.Parse(strs[i]);
            for (int i = 0; i < N; i++) {
                strs = Console.ReadLine().Split();
                for (int j = 0; j < N; j++)
                    bs[i, j] = double.Parse(strs[j]);
            }

            MakeMUV(uaz, enm, bs, A, b);
            Decomp(A);
            LUSolver(A, b);

            bool k = (0 <= b[0] && b[0] <= 1);
            bool s = (0 <= b[1] && b[1] <= 1);
            bool t = (0 <= b[2] && b[2] <= 1);
            bool u = (0 <= b[1] + b[2] && b[1] + b[2] <= 1);
            if (k & s & t & u)
                Console.WriteLine("MISS");
            else
                Console.WriteLine("HIT");
        }
    }
}