描述 Arithmetic puzzle is a type of mathematical game consisting of a mathematical equation among unknown numbers, whose digits are represented by letters. The goal is to identify the value of each letter. – wikipedia
For example, SEND+MORE=MONEY is a famous one of such puzzles. The solution is 9567+1085=10652. Note that different letters should represent different digits and the leading digit of a multi-digit number shoud not be zero.
Given an arithmetic puzzle, please find the solution.
输入 The first line contains an integer T(1 <= T <= 10), the number of puzzles.
N lines follow. Each line contains a puzzle. A puzzle consists of only ‘+’, ‘=’ and capital letters. The length of each puzzle will not exceed 100.
输出 For each puzzle output one line. If there is no solution output “No Solution” without qoutes, otherwise output the first solution by alphabetical order.
dfs(letter): // for every letter startNum = 0 // 从0开始枚举 If (notZero[ letter ]) Then // 不能为0,则从1开始 startNum = 1 EndIf Fori = startNum ... 9 Ifnot useNum[i] Then // 数字i未使用过 useNum[i] = true val[ letter ] = i // letter对应数字 i If letter islast letter Then // 如果是最后一个letter If (check(val)) Then ReturnTrue // 得到一个解 EndIf Else If (dfs(next letter)) Then // 枚举下一个letter ReturnTrue EndIf EndIf // 重置i和letter的状态 val[ letter ] = -1 useNum[i] = false EndIf EndFor ReturnFalse
check(val) w = 0 Fori = loworder .. highorder // 从低位像高位计算 s = sigma(digit atorderi) + w // val If (s % 10 != 0) Then ReturnFalse EndIf If (i == highorder && s != 0) Then ReturnFalse EndIf w = s / 10 // 进位 EndFor ReturnTrue
bool haveLetter[128] = {false}; int flag = 1; //+ int sign = 1; int pre = 0, i = 0, n = str.size(); for(; i < n; i++) { char c = str[i]; if(c == '+' || c == '-' || c == '=' ) { words.push_back({str.substr(pre, i - pre), sign}); if(c == '-') sign = -flag; elseif(c == '=') { flag = -flag; sign = flag; } if(i - pre > 1) notZero[str[pre]] = true; pre = i + 1; } else haveLetter[c] = true; } words.push_back({str.substr(pre, n - pre), sign}); for(int i = 0; i < words.size(); i++) reverse(words[i].num.begin(), words[i].num.end()); if(n - pre > 1) notZero[str[pre]] = true; for(int c = 0; c < 128; c++) if(haveLetter[c]) letters.push_back(c); }
// check the value boolcheckVal() { int w = 0, s = w; bool endFalg = false; int id = 0; while(!endFalg) { endFalg = true; s = w; for(auto word : words) { if( id < word.num.size() ) { s += val[word.num[id]] * word.sign; endFalg = false; } } if(s % 10 != 0) returnfalse; w = s / 10; id++; } return s == 0; }
// display the result voiddisp() { for(auto c : str) { if( c != '+' && c != '-' && c != '=' ) cout << val[c]; else cout << c; } cout << endl; }
dfs(i, j, s): If (i == m + 1) Then // 所有位置都枚举完 If (s == 0) Then UpdateAns() EndIf Return EndIf If (j == n + 1) Then // 该位所有字母都已经枚举完 If (s % 10 == 0) Then dfs(i + 1, 1, s / 10) // 直接将w加入s Else Return EndIf EndIf letter = getLetter(i, j) // 获得(i,j)处的字母 If (val[ letter ] != -1) Then // 该字母尚已赋值 dfs(i, j + 1, s + val[ letter ] * op[j]) Else startNum = 0 If (notZero[ letter ]) Then startNum = 1 EndIf Fori = startNum .. 9 Ifnot useNum[i] Then useNum[i] = true val[ letter ] = i dfs(i, j + 1, s + val[ letter ] * op[j]) val[ letter ] = -1 useNum[i] = false EndIf EndIf EndIf
class ArithmeticPuzzles { public: ArithmeticPuzzles(conststring s); ~ArithmeticPuzzles(){};
voidinit(); // 对变量进行初始化 voiddfs(int i, int j, int s); // 深度搜索 voiddisp(); // 显示结果 chargetLetter(int i, int j); // 获得(i,j)处的字母 voidUpdateAns(); // 更新结果/答案
dfs(i, j, s): If (i == m + 1) Then If (s == 0) Then fillAns() // 赋值剩余的数字 UpdateAns() EndIf Return EndIf If (j == n + 1) Then If (s % 10 == 0) Then dfs(i + 1, 1, s / 10) // 直接将w加入s EndIf Return EndIf letter = getLetter(i, j) // 若该字母为无用的字母,则返回-1 If (letter == -1) Then // 处理无用的字母 dfs(i, j + 1, s) Return ; End If (val[ letter ] != -1) Then dfs(i, j + 1, s + val[ letter ] * op[j]) Else startNum = 0 If (notZero[ letter ]) Then startNum = 1 EndIf Fori = startNum .. 9 Ifnot useNum[i] Then useNum[i] = true val[ letter ] = i dfs(i, j + 1, s + val[ letter ] * op[j]) val[ letter ] = -1 useNum[i] = false EndIf EndIf EndIf
class ArithmeticPuzzles { public: ArithmeticPuzzles(conststring s); ~ArithmeticPuzzles(){};
voidinit(); // 对变量进行初始化 voiddfs(int i, int j, int s); // 深度搜索 voiddisp(); // 显示结果 chargetLetter(int i, int j); // 获得(i,j)处的字母 voidUpdateAns(); // 更新结果/答案 voidfillAns();