算法
(暴搜) $O(10!)$
send
+ more
-------
money
$send = 1000s + 100e + 10n + d$
$more = 1000m + 100o + 10r + e$
注意到 $A + B = C$ 可以转变为 $A + B - C = 0$
所以可以在 $money$ 前加负号
$-money = -10000m - 1000o - 100n - 10e - y$
于是,
$send + more - money = 0 \Leftrightarrow 1000s + 91e - 90n + d - 9000m -900o + 10r - y$
直接枚举 $\{0, 1, 2, \dots, 9\}$ 的所有排列一个个尝试即可。
C++ 代码
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using std::cin;
using std::cout;
using std::map;
using std::set;
using std::vector;
using std::string;
using ll = long long;
int main() {
vector<string> s(3);
rep(i, 3) cin >> s[i];
map<char, ll> mp;
set<char> heads;
rep(i, 3) {
reverse(s[i].begin(), s[i].end());
ll co = 1;
if (i == 2) co = -1;
for (char c : s[i]) {
mp[c] += co;
co *= 10;
}
reverse(s[i].begin(), s[i].end());
heads.insert(s[i][0]);
}
if (mp.size() > 10) {
cout << "UNSOLVABLE\n";
return 0;
}
vector<int> p(10);
iota(p.begin(), p.end(), 0);
do{
int i = 0;
ll tot = 0;
for (auto x : mp) {
char c = x.first;
ll co = x.second;
if (p[i] == 0 and heads.count(c)) tot = 1e18;
tot += co * p[i];
++i;
}
if (tot == 0) {
i = 0;
for (auto& x : mp) {
x.second = p[i];
++i;
}
rep(i, 3) {
ll x = 0;
for (char c : s[i]) {
x = x * 10 + mp[c];
}
cout << x << '\n';
}
return 0;
}
} while (next_permutation(p.begin(), p.end()));
cout << "UNSOLVABLE\n";
return 0;
}