Problem:
パズル

たろう君は 9 × 9 のマス目に 1〜9 の数字を配置するパズルで遊んでいます。このパズルでは以下の規則で数字を配置しなければいけません。

同じ列に 1 つの数字はちょうど 1 回だけ現われる

同じ行に 1 つの数字はちょうど 1 回だけ現われる

二重線で区切られた 3 × 3 の各範囲には、1 つの数字はちょうど 1 回だけ現われる

例えば、下の図 1 はそのような規則を満たした配置の一つです。しかしたろう君は、図 2 のようによく規則に反した配置を作ってしまいます。左端の列に「2」が 2 回現われて、「1」が 1 回も現われず、左から2 番目の列に「1」が 2 回現われて、「2」が 1 回も現われていません。

図 1

図 2

たろう君を助けるために、数字の配置を読み込んで、その配置が規則を満たしているかどうかを調べ、規則に反していたらその場所を出力するプログラムを作成してください。3 つの規則に照らして誤っている (2 回以上現れている) 数字の前には * (半角アスタリスク)を、誤っていない数字の前には空白を表示してください。

Input

複数のデータセットが与えられます。最初の行にデータセットの数 n (n ≤ 20) が与えられます。各データセットとして、パズルの状態を示す 1 行 9 文字、9 行からなる数字列が与えられます。

Output

各データセットについて以下を出力してください。

与えられた数字と * (半角アスタリスク)と空白。誤っている数字の前には *、誤っていない数字の前には半角空白を付加する。

データセットの間に 1 行の空行を入れてください。

Sample Input

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

Output for the Sample Input

*2*1 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
*2 3 4 5 6 7 8 9 1
5 6 7 8 9 1 2 3 4
8 9 1 2 3 4 5 6 7
3 4 5 6 7 8 9 1 2
6 7 8 9 1 2 3 4 5
9*1 2 3 4 5 6 7 8

*2*1 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
*2 3 4 5 6 7 8 9 1
5 6 7 8 9 1 2 3 4
8 9 1 2 3 4 5 6 7
3 4 5 6 7 8 9 1 2
6 7 8 9 1 2 3 4 5
9*1 2 3 4 5 6 7 8

Solution in JAVA (judge verdict: Accepted)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
 
public class Main {
	private	static	BufferedReader	br = null;

	static {
		br = new BufferedReader(new InputStreamReader(System.in));
	}
 
    /**
     * @param args
     */
	public static void main(String[] args) {
		int			cnt = parseCnt();
		byte[][]	map = new byte[9][9];
		byte[]		chk = new byte[9*9*3];

		for (int l = 0; l < cnt; l++) {
			parseMap(map, chk);

			if (l > 0) {
				System.out.println();
			}

			for (int i = 0; i < map.length; i++) {
				String	out = "";
				for (int j = 0; j < map[i].length; j++) {
					int	b   = (i / 3) * 3 + j / 3;
					int	num = (int)map[i][j];

					if ((chk[i*9+num-1] | chk[81+j*9+num-1] | chk[162+b*9+num-1]) > (byte)1) {
						out += "*"+num;
					} else {
						out += " "+num;
					}
				}
				System.out.println(out);
			}
		}
	}

	private static void parseMap(byte[][] map, byte[] chk) {
		String	stdin = null;

		Arrays.fill(chk, (byte)0);
		for (int i = 0; i < map.length; i++) {
			stdin = parseStdin().replaceAll(" ", "");
			for (int j = 0; j < map[i].length; j++) {
				int		b   = (i / 3) * 3 + j / 3;
				int		num = (int)(stdin.charAt(j)-'0');
				map[i][j] = (byte)num;
				chk[i*9+num-1]++;
				chk[81+j*9+num-1]++;
				chk[162+b*9+num-1]++;
			}
		}
	}

	private static int parseCnt() {
		int		cnt = 0;
		String	str = null;

		if ((str = parseStdin()) != null) {
			cnt = Integer.parseInt(str);
		}

		return cnt;
	}

	private static String parseStdin() {
		String  stdin = null;

		try {
			String  tmp = br.readLine();
			if (tmp != null) {
				if (!tmp.isEmpty()) stdin = tmp;
			}
		}
		catch (IOException e) {}

		return stdin;
	}
}