Problem:
Blur

図 1 のような 10×10 のマス目の「布」があり、（1，2）のようにX座標・Y座標の値の対でマス目を示すことにします。座標値は 0 から始まる整数とします。例えば、図 1 の◎の座標は (1, 2) です。
この「布」に染料を少しずつたらして染物を作ります。たらす染料の滴には「大」「中」「小」の 3 サイズがあり、染料の滴の落ちたマス目を中心に図 1 のように周囲も色がつきます。図 1 で☆が中心、○が色のにじむ範囲です。

「布」は、最初は「まっしろ」つまり、どのマス目も色の濃さを示す値が 0 とします。染料の滴が落ちるごとに値が 1 ずつ増えていきます。「小」が（1, 2）、「中」が（3, 2）に落ちた場合、各マス目の値は図 2 の左のようになります。染料がもったいないので、図 2 の右に示すようなにじむ範囲が布の外にはみ出すような染料の落とし方はしないことになっています。また、同じ場所に複数の染料をたらすこともあります。

このような作業を何回か繰り返した結果、布にすばらしい模様が浮かび上がりましたが、残念なことに、うっかり作業経過を記録し忘れてしまいました。どうにもさっぱり思い出せませんが、かろうじて、落とした染料の滴数は覚えていました。あなたは、すばらしい染物を再現しなければなりません。すばらしい染物のデータを読みこんで、どこに、どのような染料をたらしたかを出力するプログラムを作成してください。なお、落とした染料の滴数は 12 以下とします。

入力

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

最初の 1 行に落とした染料の滴数 n が与えられます。次の行から 10 行に各座標の色の濃さが空白区切りで与えられます。

出力

出力は n 行からなります。染料の滴の「大」を 3、「中」を 2、「小」を 1 で表し、落とした染料ごとに、そのX座標、Y座標、滴の大きさを空白で区切って1行に出力してください。

染料のたらし方はどのような順番で出力しても良いものとします。

入力例1

2
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 1 1 1 0 0 0 0 0
0 0 0 1 0 0 0 1 1 1
0 0 0 0 0 0 0 1 1 1
0 0 0 0 0 0 0 1 1 1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

出力例1

3 2 1
8 4 2

入力例2

6
0 0 1 0 0 0 0 0 0 0
0 1 1 1 0 0 0 0 0 0
1 1 1 1 1 1 1 1 0 0
0 1 1 1 1 1 1 1 0 0
0 0 1 1 1 3 1 1 0 0
0 0 1 1 3 1 1 1 0 0
0 0 1 1 1 1 1 1 1 0
0 0 1 1 1 1 1 1 1 1
0 0 0 0 0 0 1 1 1 0
0 0 0 0 0 0 0 1 0 0

出力例2

2 2 3
7 7 3
6 3 2
3 6 2
4 4 1
5 5 1

Solution in C# (judge verdict: Accepted)

using System;
using System.Linq;

namespace V0091_1{
    public class Program{
        const int Size = 10;

        readonly int[][] _dx ={
            new[]{0, 1, 0, -1, 0},
            new[]{0, 1, 0, -1, 0, 1, 1, -1, -1},
            new[]{0, 1, 0, -1, 0, 1, 1, -1, -1, 2, -2, 0, 0}
        };

        readonly int[][] _dy ={
            new[]{0, 0, 1, 0, -1},
            new[]{0, 0, 1, 0, -1, 1, -1, 1, -1},
            new[]{0, 0, 1, 0, -1, 1, -1, 1, -1, 0, 0, 2, -2}
        };

        readonly int[] _cx = {-2, -1};
        readonly int[] _cy = {-2, -2};

        readonly int _n;
        readonly int[][] _cloth;
        readonly int[,] _res = new int[Size * Size, 3];
        int _blur;
        bool _end;

        Program(){
            var sr = new StreamReader();
            _n = sr.Next<int>();
            _cloth = sr.Next<int>(Size, Size);
            _blur = _cloth.SelectMany(x => x).Sum();
        }

        void Solve(){
            Dfs(0, 0);
        }

        void Dfs(int cnt, int pos){
            if(_end) return;
            if(pos == Size * Size) return;

            if(cnt == _n){
                if(_blur == 0){
                    _end = true;
                    for(var i = 0; i < Size * Size; i++){
                        for(var j = 0; j < 3; j++){
                            for(var k = 0; k < _res[i, j]; k++){
                                Console.WriteLine("{0} {1} {2}", i % Size, i / Size, j + 1);
                            }
                        }
                    }
                }
                return;
            }

            for(var i = 0; i < 3; i++){
                if(Check(pos, i)){
                    Paint(pos, i, 1);
                    Dfs(cnt + 1, pos);
                    Paint(pos, i, -1);
                }
            }

            if(IsClearn(pos + 1)){
                Dfs(cnt, pos + 1);
            }
        }

        void Paint(int pos, int s, int a){
            _res[pos, s] += a;
            _blur -= _dx[s].Length * a;
            var x = pos % Size;
            var y = pos / Size;
            for(var i = 0; i < _dx[s].Length; i++){
                var tx = x + _dx[s][i];
                var ty = y + _dy[s][i];
                _cloth[ty][tx] += -a;
            }
        }

        bool Check(int pos, int s){
            var x = pos % Size;
            var y = pos / Size;
            for(var i = 0; i < _dx[s].Length; i++){
                var tx = x + _dx[s][i];
                var ty = y + _dy[s][i];
                if(!IsInside(tx, ty) || _cloth[ty][tx] == 0) return false;
            }
            return true;
        }

        bool IsClearn(int pos){
            var x = pos % Size;
            var y = pos / Size;
            for(var i = 0; i < _cx.Length; i++){
                var tx = x + _cx[i];
                var ty = y + _cy[i];
                if(IsInside(tx, ty) && _cloth[ty][tx] != 0) return false;
            }
            return true;
        }

        bool IsInside(int x, int y){
            return 0 <= x && x < Size && 0 <= y && y < Size;
        }

        public static void Main(string[] args){
            new Program().Solve();
        }
    }

    public static class ExMethod{
        public static T[][] ToJaggedArray<T>(this T[,] src){
            var x = src.GetLength(1);
            var y = src.GetLength(0);
            var ret = new T[y][];

            for(var i = 0; i < y; i++){
                ret[i] = new T[x];
                for(var j = 0; j < x; j++){
                    ret[i][j] = src[i, j];
                }
            }

            return ret;
        }
    }

    public class StreamReader{
        private readonly char[] _c = {' '};
        private int _index = -1;
        private string[] _input = new string[0];
        private readonly System.IO.StreamReader _sr = new System.IO.StreamReader(Console.OpenStandardInput());

        public T Next<T>(){
            if(_index == _input.Length - 1){
                _index = -1;
                while(true){
                    string rl = _sr.ReadLine();
                    if(rl == null){
                        if(typeof(T).IsClass) return default(T);
                        return (T)typeof(T).GetField("MinValue").GetValue(null);
                    }
                    if(rl != ""){
                        _input = rl.Split(_c, StringSplitOptions.RemoveEmptyEntries);
                        break;
                    }
                }
            }
            return (T)Convert.ChangeType(_input[++_index], typeof(T), System.Globalization.CultureInfo.InvariantCulture);
        }

        public T[] Next<T>(int x){
            var ret = new T[x];
            for(var i = 0; i < x; ++i) ret[i] = Next<T>();
            return ret;
        }

        public T[][] Next<T>(int y, int x){
            var ret = new T[y][];
            for(var i = 0; i < y; ++i) ret[i] = Next<T>(x);
            return ret;
        }
    }
}