Problem:
ブロック

A さんの家に親戚の B 君がやってきました。彼は 3 歳でブロックが大好きです。彼が持っているブロックは図 1 のような形をしています。

図1

B 君はボードの上にブロックを敷き詰めています。彼に「何を作っているの?」と聞くと、彼は「迷路!!」と元気よく答えました。彼の言う迷路とは、スタートからゴールまで側面が接している、同じ色のブロックだけでたどることができるブロックの配置のことだそうです。図 2 は黄色のブロックにより、左上(スタート)から右下(ゴール)へ迷路ができていることを表しています。

図2

無邪気に遊んでいる B 君を横目に、プログラマーであるあなたは、ブロックの並びが迷路となっているかを確かめてみることにしました。

ブロックの情報とスタート、ゴールの座標を入力とし、ブロックが迷路となっていれば OK 、なっていなければ NG を出力するプログラムを作成してください。 ボードは横方向に w 、縦方向に h の大きさをもち、 左上の座標は(1 , 1)、右下の座標は(w, h)とします。ブロックは 2 × 4 の長方形ですべて同じ大きさです。ブロックの色 c は 1 (白)、2 (黄)、3 (緑)、4 (青)、5 (赤) のいずれかです。ブロックのボード上での向き d は 横方向に長い場合 0 、 縦方向に長い場合 1 とします。 ブロックの位置はブロックの左上の座標 (x, y) によって表されます。なお、ブロックの位置は他のブロックと重なることは無く、ボードからはみ出すこともありません。

Input

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

w h
xs ys
xg yg
n
c1 d1 x1 y1
c2 d2 x2 y2
:
cn dn xn yn

1 行目にボードの大きさw, h (4 ≤ w, h ≤ 100) が与えられます。2 行目にスタートの座標 xs, ys、3 行目にゴールの座標 xg, yg が与えられます。

4 行目にブロックの個数 n が与えられます。続く n 行に i 番目のブロックの色 ci、向き di、位置 xi, yi が与えられます。

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

Output

入力データセットごとに、判別結果を１行に出力します。

Sample Input

20 20
1 1
9 9
7
2 0 1 1
5 1 1 3
2 1 3 3
1 1 5 2
5 1 7 3
2 0 2 7
2 0 6 8
20 20
9 9
1 1
6
2 0 1 1
1 0 5 1
2 1 1 3
5 0 1 7
3 1 5 5
4 1 8 5
0 0

Output for the Sample Input

OK
NG

Solution in C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;

namespace AOJ
{
    class Program
    {

        const int BLOCK_W = 2;
        const int BLOCK_H = 4;

        private int w, h;
        private int[,] borad;
        private int start_x;
        private int start_y;
        private int goal_x;
        private int goal_y;

        private bool isToGoal(int c,int x,int y){

            if (x > w || y > h) return false;
            if (borad[x, y] != c) return false;
            if (x == goal_x && goal_y == y) return true;

            borad[x, y] += 10; //通過フラグ

            bool r = false;
            r = isToGoal(c, x + 1, y);
            if (!r) r = isToGoal(c, x - 1, y);
            if (!r) r = isToGoal(c, x, y + 1);
            if (!r) r = isToGoal(c, x, y - 1);
            return r;
        }

        private string solve(int p_w,int p_h)
        {
            w = p_w;
            h = p_h;
            string[] tmp_start = Console.ReadLine().Split(new char[] { ' ' });
            string[] tmp_goal = Console.ReadLine().Split(new char[] { ' ' });
            start_x = int.Parse(tmp_start[0]);
            start_y = int.Parse(tmp_start[1]);
            goal_x = int.Parse(tmp_goal[0]);
            goal_y = int.Parse(tmp_goal[1]);

            borad = new int[w+1,h+1];
            
            int n = int.Parse(Console.ReadLine());

            //ブロック読み込み
            for (int i = 0; i < n; i++)
            {
                string[] block_i = Console.ReadLine().Split(new char[] { ' ' });
                int color = int.Parse(block_i[0]);
                int d = int.Parse(block_i[1]);
                int x = int.Parse(block_i[2]);
                int y = int.Parse(block_i[3]);

                int x_e,y_e;
                if (d == 0)
                {
                    x_e = x + BLOCK_H - 1;
                    y_e = y + BLOCK_W - 1;
                }
                else
                {
                    x_e = x + BLOCK_W - 1;
                    y_e = y + BLOCK_H - 1;
                }
                for(int x_i = x;x_i<= x_e;x_i++){
                    for (int y_i = y; y_i <= y_e;y_i++ )
                    {
                        borad[x_i, y_i] = color;
                    }   
                }
            }

            //for (int i = 0; i < w; i++)
            //{
            //    for (int j = 0; j < h; j++)
            //    {
            //        Console.Write(borad[i, j].ToString() + ",");
            //    }
            //    Console.WriteLine();
            //}

            for (int c = 1; c <= 5; c++)
            {
                if (isToGoal(c, start_x, start_y)) return "OK";
            }
            return "NG";

        }
        
        static void Main(string[] args)
        {
            Program obj = new Program();
            while (true) {
                string[] s = Console.ReadLine().Split(new char[] { ' ' });
                if (s[0] == "0" && s[1] == "0") break;
                Console.WriteLine(obj.solve(int.Parse(s[0]), int.Parse(s[1])));
            }
        }
    }
}