AtCoder Beginner Contest 031 D - 語呂合わせ
やるだけなので解法面では何もないですが、題材と問題の仕方は好きです。
D - 語呂合わせ
解法
それぞれの数字について$s_i$の長さだけ決めればよい。 $1 \le |s_i| \le 3$であるので、探索空間は$3^9$と小さい。
実装
#include <iostream>
#include <vector>
#include <map>
#define repeat(i,n) for (int i = 0; (i) < (n); ++(i))
#define repeat_from(i,m,n) for (int i = (m); (i) < (n); ++(i))
using namespace std;
bool solve(int y, int xv, int xw, vector<string> const & v, vector<string> const & w, map<int,string> & s) {
if (y == v.size()) return true;
if (xv == v[y].size() and xw == w[y].size()) return solve(y+1, 0, 0, v, w, s);
if (xv == v[y].size() or xw == w[y].size()) return false;
int n = v[y][xv] - '0';
if (s.count(n)) {
string t = s[n];
if (w[y].substr(xw, t.length()) == t) {
return solve(y, xv+1, xw+t.length(), v, w, s);
} else {
return false;
}
} else {
repeat_from (l,1,3+1) {
string t = w[y].substr(xw, l);
if (t.length() != l) break;
s[n] = t;
if (solve(y, xv+1, xw+l, v, w, s)) return true;
}
s.erase(n);
}
return false;
}
int main() {
int k, n; cin >> k >> n;
vector<string> v(n), w(n); repeat (i,n) cin >> v[i] >> w[i];
map<int,string> s;
solve(0, 0, 0, v, w, s);
repeat (i,k) cout << s[i+1] << endl;
return 0;
}