ICPC国内予選C
模擬国内予選と国内予選の参加記も書くつもりですが、取り急ぎCのソースだけ!
Cは一見楽勝に見えてそのまま書き始めると実にかったるい(next_permutationを使ってしまったり)ですが、問題文を読み込めばDFSですっきり書けます。
#include <iostream> #include <set> #include <vector> using namespace std; int value[10]; bool used[10]; bool not_zero[10]; inline int Eval(const vector<int>& word) { int ret = 0; for (int i = 0; i < word.size(); ++i) ret = ret * 10 + value[word[i]]; return ret; } int Dfs(int depth, int alphabet_size, const vector<vector<int> >& words) { if (depth == alphabet_size) { int left = 0; for (int i = 0; i < words.size() - 1; ++i) left += Eval(words[i]); int right = Eval(words.back()); return left == right; } else { int ret = 0; for (int i = not_zero[depth] ? 1 : 0; i < 10; ++i) { if (used[i]) continue; used[i] = true; value[depth] = i; ret += Dfs(depth + 1, alphabet_size, words); used[i] = false; } return ret; } } int main() { int N; while (cin >> N, N) { vector<string> v(N); set<char> alph; for (int i = 0; i < N; ++i) { cin >> v[i]; for (int j = 0; j < v[i].size(); ++j) alph.insert(v[i][j]); } string alphabet(alph.begin(), alph.end()); vector<vector<int> > words(N); for (int i = 0; i < v.size(); ++i) for (int j = 0; j < v[i].size(); ++j) words[i].push_back(alphabet.find(v[i][j])); fill(not_zero, not_zero + 10, false); for (int i = 0; i < v.size(); ++i) if (v[i].size() > 1) not_zero[alphabet.find(v[i][0])] = true; fill(used, used + 10, false); cout << Dfs(0, alphabet.size(), words) << endl; } }
以上64行。
あ、もちろん本番はnext_permutationを使って無駄にカウントしてしまったのを無理矢理factorialで割りつじつま合わせて提出キめました。