import java.io.*; import java.util.*; /** * 2009年 国内予選C問題 覆面算 * http://www.waseda.jp/assoc-icpc2009/preliminarity/contest/all_ja.html#section_C * * 読み込んだデータは以下の3つのデータ形式として記憶する。 * 1. 各文字とその文字にセットした数値(初期値=セットしていない数値は、-1) * 2. 各桁ごとの文字、最後の文字は足し算後の結果の数字を隠す文字になる。 * 3. 0にセットできない文字一覧 * * 処理は次のように行う。 * 1. 0桁、0文字目から未セットの文字を捜す。 * 2. 発見した未セット文字のタイプによって以下の2つに分岐する。 * 2.1. 発見した未セット文字が足し算の結果を表わす場合、足し算結果の数値をセットする。 * 2.2. 上記以外の場合、0から9までの数値を1つづつセットするループに入る。この間に処理は再帰的に1.に戻る。 * 3. 未セット文字を発見できない場合、桁が変わるときには、その桁の足し算が正しいかを確認する。 * 3.1. 桁の演算が正しくない場合、処理は終わる(再帰している処理が終わる) * 3.2. 桁が正しく、かつ、すべての桁について調査し終わった場合、結果の個数をインクリメントする。 * * */ public class Exp2009_C { /** メイン関数、プログラムはここから始まる。 */ public static void main(String[] args) throws Exception{ // ファイル読み込み BufferedReader br = new BufferedReader(new FileReader(args[0])); String line = null; while(null!=(line=br.readLine())){ int num = Integer.parseInt(line); if(num == 0){ break; } // 各文字とその文字にセットされた値 HashMap chars = new HashMap(); // 桁ごとの文字 Vector> exps = new Vector>(); // ゼロにセットできない文字セット Vector nonzeros = new Vector(); // 各行(項)の読み込み Vector terms = new Vector(); int max_length = -1; for(int cnt=0;cnt()); } for(int cnt=0;cnt chars,Vector nonzeros,Character c,int value){ if(value == 0 && nonzeros.contains(c)==true){ return false; } for(Map.Entry entry : chars.entrySet()){ if(entry.getValue().intValue()==value){ return false; } } return true; } /** 合計を示す項以外の項の合計を計算する。 */ public static int sum(HashMap chars,Vector exp,int up){ int sum = up; for(int cnt=0;cnt chars,Vector exp,int up,int[] nextup){ int sum = sum(chars,exp,up); if(sum%10 == chars.get(exp.get(exp.size()-1)).intValue()){ nextup[0] = sum/10; return true; } return false; } /** 1桁目から順に、値がセットされていない文字を見つけ、その文字が合計を示す文字の場合、合計になる数字をセットする。 * 合計以外の文字の場合には、0から順に9までをセットする。そのループの間にこの関数が再帰的に呼ばれ、再度チェックが行われる。 */ public static void next(HashMap chars,Vector> exps,Vector nonzeros,int[] count){ Character tag = null; int sum = -1; int up = 0; boolean looped = true; for(int keta=0;keta exp = exps.get(keta); for(int idx=0;idx chars,Vector> exps,Vector nonzeros){ System.out.printf("文字一覧\n"); for(Map.Entry entry : chars.entrySet()){ System.out.printf("%c : %d\n",entry.getKey(),entry.getValue()); } System.out.printf("桁ごと\n"); for(int cnt1=0;cnt1 strs = exps.get(cnt1); for(int cnt2=0;cnt2