题目链接
题意
现实生活中,你时常会遇到许多许多而且越来越长的电话号码。你需要记住这类型的号码。 例如按下面的图示,把字母划分到特定的数字上,是一种很容易就能把数字记住的方法:
1 ij 2 abc 3 def
4 gh 5 kl 6 mn
7 prs 8 tuv 9 wxy
0 oqz
按这种方法:每个字或一个词组可被代替成一组特定的数字,那么,你只可以通过记住一些词就能记住相应电话号码。 如果可以找出一种单词与个人电话号码的简单关系,它是很有吸引力的。例如你的一个棋友的电话号码是941837296,你可以用 WHITEPAWN来代替;又如你可以用BUULDOG来代替你的一个喜爱的老师的电话号码:2855304。
问题
对给定的给定的数字和单词表,求出一个最简短的单词序列(也就是得出一尽可能短的单词来代替相应的数字)。这种对应关系要求符合上图所描述的关系。
输入
输入包含若干组的测试数据。每组测试点的第一行是你所要记住的电话号码。这个号码最多有100个数位。测试的第二行是单词总数(最大为50000个)。以下的每一行是只包含一个单词,单词长度最大限制为50个字母。整个输入文件的大小不超过300KB。 输入文件的最后一行以-1作为结束标志。
输出
输出文件的每一行为找到的最短单词序列。每个单词间用一个空格隔开。如果没有解决方案,则输出“No solution.”。 如果有多个单词满足条件,可以从中选择任一个单词输出。
样例
input
7325189087
5
it
your
reality
real
our
4294967296
5
it
your
reality
real
our
-1
output
reality our
No solution.
思路
首先,因为每个字母都对应唯一一个数字,我们完全可以将所有给定单词转换为数字序列。
那么,现在的问题就是用最少的数字串组成主串,我们用kmp找出每个数字串在主串中匹配的位置。
若匹配成功,那么在主串中匹配的首尾位置可以看作是一个权值为1的单向边,问题就可以转换为求0~n的最短路问题。
因为这题的每条边的先后次序是确定的,所以直接用dp解决即可。
代码