传送门
直接求出每个串出现位置,DP即可。
#include <bits/stdc++.h>
using namespace std;
#define prt(k) cerr<<#k" = "<<k<<endl
typedef long long LL;
const int inf = 0x3f3f3f3f;
#define pb push_back
const int N = 50500;
const int M = N * 50;
int ch[M][10], fail[M], id[M], len[N];
int L; int n;
map<char, int> mp;
namespace AC {
int newnode() { memset(ch[L],-1,sizeof ch[L]); id[L++] = 0; return L-1; }
void init() { L = 0; newnode(); }
void insert(char s[], int ID)
{
int u = 0, len = strlen(s);
for (int i=0;i<len;i++) {
int c = s[i] - '0';
if (ch[u][c] == -1) ch[u][c]= newnode();
u = ch[u][c];
}
id[u] = ID;
}
void AC_build()
{
queue<int> q;
for (int i=0;i<10;i++) {
int &v = ch[0][i];
if (v != -1) {
q.push(v);
fail[v] = 0;
} else v = 0;
}
while (!q.empty()) {
int u = q.front(); q.pop();
for (int i=0;i<10;i++) {
int &v = ch[u][i];
if (v==-1) {
v = ch[fail[u]][i];
} else {
fail[v] = ch[fail[u]][i];
q.push(v);
}
}
}
}
vector<int> pos[N];
void query(char buf[])
{
int n = strlen(buf);
int u=0;
for(int i=0;i<n;i++)
{
u=ch[u][buf[i]-'0'];
for(int v=u;v!=0;v=fail[v])
{
if (id[v] > 0) {
pos[i-len[id[v]]+1].push_back(id[v]);
}
}
}
} };
using namespace AC;
#define For(i,l,r) for (char i=l;i<=r;i++)
char T[233], s[N][52], old[N][55];
int TL;
int dp[N];
int pre[N];
int main()
{
mp['i'] = mp['j'] = 1;
mp['a'] = mp['b'] = mp['c'] = 2;
For(i,'d','f') mp[i]=3;
For(i, 'g', 'h') mp[i] = 4;
For(i,'k','l') mp[i] = 5;
For(i,'m','n') mp[i] = 6;
For(i,'p','s') mp[i] = 7;
For(i, 't', 'v') mp[i] = 8;
For(i, 'w', 'y') mp[i] = 9;
mp['o'] = mp['q'] = mp['z'] = 0;
while (scanf("%s", T) == 1 ) {
if (strcmp(T,"-1")==0) break;
TL = strlen(T);
for (int i=0;i<TL;i++) pos[i].clear();
cin>>n;
L = 0; newnode();
for (int i=1;i<=n;i++) {
scanf("%s", s[i]);
len[i] = strlen(s[i]);
strcpy(old[i], s[i]);
for (int j=0;j<len[i];j++) s[i][j] = mp[s[i][j]] + '0';
insert(s[i], i);
}
AC_build();
query(T);
int m = TL;
memset(dp, 63, sizeof dp);
memset(pre, -1, sizeof pre);
dp[0] = 0;
for (int i=0;i<m;i++) {
for (auto x : pos[i]) {
if (dp[i+len[x]] > dp[i] + 1) {
dp[i+len[x]] = dp[i] + 1;
pre[i+len[x]] = x;
}
}
}
if (dp[m] == inf) { puts("No solution."); continue; }
stack<int> stk;
int i = m;
while (i!=0 && pre[i]!=-1) {
stk.push(pre[i]);
i -= len[pre[i]];
}
printf("%s", old[stk.top()]);
stk.pop();
while (!stk.empty()) {
printf(" %s", old[stk.top()]);
stk.pop();
}
putchar(10);
}
return 0;
}