Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

虫食い算

足し算は筆算で簡単に計算できますが、もし、いくつかの数字が欠けていたら、欠けている数字を埋めるのは簡単でしょうか？ 例えば、以下のような筆算において、１から９の数字が一度しか現れないという条件があるとき、ＣとＥのマスに入る数字はいくつになるでしょう？ この場合、Ｃに入るのは８，Ｅに入るのは５が正解となります。このように、数字がいくつか欠けている演算を虫食い算と呼びます。

１から９の数字が一度しか現れないという条件はそのままで、以下のようにもっとたくさんの数字が欠けていたら、正解となる数字の埋め方は一通りしかないのでしょうか？ 実は、必ず一通りに決まるとは限りません。

上の図のような形をした虫食い算の、ＡからＩの各マスの情報が与えられたとき、正しい埋め方が何通りあるかを出力するプログラムを作成せよ。

Input

入力は以下の形式で与えられる。

A B C D E F G H I

１行に、虫食い算の Ａ から Ｉ のマスに入っている数字の情報が与えられる。ただし、与えられた値が -1 のときは、そのマスの数字が欠けていることを表す。-1 以外の値は、1 から 9 の整数のいずれかで、それらの間に重複はない。

Output

正しい埋め方が何通りあるかを１行に出力する。

Sample Input 1

7 6 -1 1 -1 9 2 3 4

Sample Output 1

1

Sample Input 2

7 6 5 1 8 9 2 3 4

Sample Output 2

0

Sample Input 3

-1 -1 -1 -1 -1 -1 8 4 6

Sample Output 3

12

Sample Input 4

-1 -1 -1 -1 -1 -1 -1 -1 -1

Sample Output 4

168

Solution in JAVA (judge verdict: Accepted)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import static java.lang.Integer.parseInt;

/**
 * Alphametic
 */
public class Main {

	static int[][] nums;
	static boolean[] used;

	static int[][] pos = {
			{0, 2},
			{1, 1}, {1, 2},
			{2, 0}, {2, 1}, {2, 2},
			{3, 0}, {3, 1}, {3, 2},
	};

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String line;
		String[] words;

		words = br.readLine().split(" ");

		nums = new int[4][3];
		used = new boolean[10];

		for (int i = 0; i < words.length; i++) {
			int n = parseInt(words[i]);
			if (n != -1) used[n] = true;
			nums[pos[i][0]][pos[i][1]] = n;
		}

		System.out.println(solve(0));
	}

	static int solve(int idx) {

		if (idx == pos.length) {
			if (check()) return 1;
			else return 0;
		}

		//
		int i = pos[idx][0];
		int j = pos[idx][1];
		
		int ret = 0;

		outer:
		if (nums[i][j] == -1) {
			for (int k = 1; k <= 9; k++) {
				if (!used[k]) {
					nums[i][j] = k;
					used[k] = true;
					ret += solve(idx + 1);
					nums[i][j] = -1;
					used[k] = false;
				}
			}
		} else {
			ret = solve(idx + 1);
		}

		return ret;
	}

	static boolean check() {

		int[] a = new int[4];

		for (int i = 0; i < 4; i++) {
			a[i] = nums[i][0] * 100 + nums[i][1] * 10 + nums[i][2];
		}

		return a[0] + a[1] + a[2] == a[3];
	}
}