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 JAVA (judge verdict: Memory Limit Exceeded)

import java.util.LinkedList;
import java.util.Scanner;

public class Main {
	
	public static final int SIZE = 10;
	
	public static boolean is_ok(int x, int y){
		return x >= 0 && x < SIZE && y >= 0 && y < SIZE;
	}
	
	public static boolean big_ok(int x, int y, int[][] map){
		if(!is_ok(x - 2, y - 2) || !is_ok(x + 2, y + 2)){
			return false;
		}
		
		for(int dy = -2; dy <= 2; dy++){
			for(int dx = -2; dx <= 2; dx++){
				if(Math.abs(dx) + Math.abs(dy) > 2){
					continue;
				}
				
				if(map[y + dy][x + dx] <= 0){
					return false;
				}
			}
		}
		
		return true;
	}
	
	public static boolean middle_ok(int x, int y, int[][] map){
		if(!is_ok(x - 1, y - 1) || !is_ok(x + 1, y + 1)){
			return false;
		}
		
		for(int dy = -1; dy <= 1; dy++){
			for(int dx = -1; dx <= 1; dx++){
				if(map[y + dy][x + dx] <= 0){
					return false;
				}
			}
		}
		
		return true;
	}
	
	public static boolean small_ok(int x, int y, int[][] map){
		if(!is_ok(x - 1, y - 1) || !is_ok(x + 1, y + 1)){
			return false;
		}
		
		for(int dy = -1; dy <= 1; dy++){
			for(int dx = -1; dx <= 1; dx++){
				if(Math.abs(dx) + Math.abs(dy) > 1){
					continue;
				}
				
				if(map[y + dy][x + dx] <= 0){
					return false;
				}
			}
		}
		
		return true;
	}
	
	public static int general_ok(int x, int y, int[][] map){
		int ret = 3;
		
		if(!is_ok(x - 1, y - 1) || !is_ok(x + 1, y + 1)){
			return 0;
		}else if(!is_ok(x - 2, y - 2) || !is_ok(x + 2, y + 2)){
			ret = 2;
			
			for(int dy = -1; dy <= 1; dy++){
				for(int dx = -1; dx <= 1; dx++){
					if(Math.abs(dx) + Math.abs(dy) <= 1 && map[y + dy][x + dx] <= 0){
						return 0;
					}else if(map[y + dy][x + dx] <= 0){
						ret = Math.min(ret, 1);
					}
				}
			}
			
			return ret;
		}else{
			for(int dy = -2; dy <= 2; dy++){
				for(int dx = -2; dx <= 2; dx++){
					if(Math.abs(dx) + Math.abs(dy) <= 1 && map[y + dy][x + dx] <= 0){
						return 0;
					}else if(Math.abs(dx) == 1 && Math.abs(dy) == 1 && map[y + dy][x + dx] <= 0){
						ret = Math.min(ret, 1);
					}else if(Math.abs(dx) + Math.abs(dy) <= 2 && map[y + dy][x + dx] <= 0){
						ret = Math.min(ret, 2);
					}
				}
			}
			
			//System.out.println(ret);
			
			return ret;
		}
	}
	
	public static void attach_big(int x, int y, boolean flag, int[][] map){
		for(int dy = -2; dy <= 2; dy++){
			for(int dx = -2; dx <= 2; dx++){
				if(Math.abs(dx) + Math.abs(dy) > 2){
					continue;
				}
				
				map[y + dy][x + dx] += flag ? -1 : 1;
			}
		}
	}
	
	public static void attach_middle(int x, int y, boolean flag, int[][] map){
		for(int dy = -1; dy <= 1; dy++){
			for(int dx = -1; dx <= 1; dx++){
				map[y + dy][x + dx] += flag ? -1 : 1;
			}
		}
	}
	
	public static void attach_small(int x, int y, boolean flag, int[][] map){
		for(int dy = -1; dy <= 1; dy++){
			for(int dx = -1; dx <= 1; dx++){
				if(Math.abs(dx) + Math.abs(dy) > 1){
					continue;
				}
				
				map[y + dy][x + dx] += flag ? -1 : 1;
			}
		}
	}
	
	public static boolean is_over(int x, int y, int[][] map){
		if(!is_ok(x, y - 2)){
			return false;
		}
		
		return map[y - 2][x] > 0;
	}
	
	public static void disp(int[][] map){
		for(int i = 0; i < SIZE; i++){
			for(int j = 0; j < SIZE; j++){
				System.out.print(map[i][j] + " ");
			}
			System.out.println();
		}
		System.out.println("-------------------");
	}
	
	public static void err(int[][] map){
		for(int i = 0; i < SIZE; i++){
			for(int j = 0; j < SIZE; j++){
				System.err.print(map[i][j] + " ");
			}
			System.err.println();
		}
		System.err.println("-------------------");
	}
	
	public static boolean answer = false;
	public static int max = 0; 
	public static int[][] map;
	public static LinkedList<Integer> x_list, y_list, type_list;
	
	public static void dfs(int x, int y, int deep){
		//System.out.println(deep + " " + x + " " + y + " " + type_list);
		//disp(map);
		
		if(deep > max){
			return;
		}else if(answer){
			return;
		}
		
		for(int _y = y; _y < SIZE + 2; _y++){
			for(int _x = _y == y ? x : 0; _x < SIZE; _x++){
				if(answer){
					return;
				}
				//boolean flag = false;
				//System.out.println(deep + " " + _x + " " + _y + " " + type_list);
				//disp(map);
				
				final int check = general_ok(_x, _y, map);
				
				if(check >= 3){
					attach_big(_x, _y, true, map);
					
					x_list.addLast(_x);
					y_list.addLast(_y);
					type_list.add(3);
					
					dfs(_x, _y, deep + 1);
					if(answer){
						return;
					}
					
					x_list.removeLast();
					y_list.removeLast();
					type_list.removeLast();
					attach_big(_x, _y, false, map);
				}
				
				if(check >= 2){
					attach_middle(_x, _y, true, map);
					x_list.addLast(_x);
					y_list.addLast(_y);
					type_list.add(2);
					
					dfs(_x, _y, deep + 1);
					if(answer){
						return;
					}
					
					x_list.removeLast();
					y_list.removeLast();
					type_list.removeLast();
					attach_middle(_x, _y, false, map);
				}
				
				if(check >= 1){
					attach_small(_x, _y, true, map);
					x_list.addLast(_x);
					y_list.addLast(_y);
					type_list.add(1);
					
					dfs(_x, _y, deep + 1);
					if(answer){
						return;
					}
					
					x_list.removeLast();
					y_list.removeLast();
					type_list.removeLast();
					attach_small(_x, _y, false, map);
				}
				
				if(check == 0 && is_over(_x, _y, map)){
					return;
				}
			}
		}
		
		//if(deep != max){
		//	return;
		//}
		
		answer = true;
		return;
	}
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		final int n = sc.nextInt();
			
		map = new int[SIZE][SIZE];
		for(int i = 0; i < SIZE; i++){
			for(int j = 0; j < SIZE; j++){
				map[i][j] = sc.nextInt();
			}
		}
			
		x_list = new LinkedList<Integer>();
		y_list = new LinkedList<Integer>();
		type_list = new LinkedList<Integer>();
		
		max = n;
		
		dfs(0, 0, 0);
		
		if(!answer){
			System.err.println("error");
			err(map);
		}
		
		while(!x_list.isEmpty()){
			final int x = x_list.poll();
			final int y = y_list.poll();
			final int type = type_list.poll();
				
			System.out.println(x + " " + y + " " + type);
		}
	}

}