In the present world you frequently meet a lot of call numbers and they are going to be longer and longer. You need to remember such a kind of numbers. One method to do it in an easy way is to assign letters to digits as shown in the following picture:
1 ij    2 abc   3 def
4 gh 5 kl 6 mn
7 prs 8 tuv 9 wxy
0 oqz
This way every word or a group of words can be assigned a unique number, so you can remember words instead of call numbers. It is evident that it has its own charm if it is possible to find some simple relationship between the word and the person itself. So you can learn that the call number 941837296 of a chess playing friend of yours can be read as WHITEPAWN, and the call number 2855304 of your favourite teacher is read BULLDOG.
Write a program to find the shortest sequence of words (i.e. one having the smallest possible number of words) which corresponds to a given number and a given list of words. The correspondence is described by the picture above.

Input

Input contains a series of tests. The first line of each test contains the call number, the transcription of which you have to find. The number consists of at most 100 digits. The second line contains the total number of the words in the dictionary (maximum is 50 000). Each of the remaining lines contains one word, which consists of maximally 50 small letters of the English alphabet. The total size of the input doesn't exceed 300 KB. The last line contains call number −1.

Output

Each line of output contains the shortest sequence of words which has been found by your program. The words are separated by single spaces. If there is no solution to the input data, the line contains text “No solution.”. If there are more solutions having the minimum number of words, you can choose any single one of them.
 
Link:http://acm.timus.ru/problem.aspx?space=1&num=1002
题目大意:每个字母有对应的数字,那么,为了方便电话号码的记忆,我们可以把这些数字换成多个单词来方便记忆。现在给出一串数字,和多个单词,要求用最少的单词来表示出所有的数字,有多个答案任意给出一个即可。
思路:乍眼看去好像有点小难……仔细想想,首先,因为每个字母都对应着一个数字,可以把这些字母都替换成数字,这样就变成了数字与数字之间的匹配。
然后,题目可以解释为:给你多个字符串(只包含数字),用最少的字符串组成一个特定的字符串。
于是,我们可以发现每个字符串所能覆盖的位置都是固定的,用KMP算法可以把他们都找出来。
这个是不是有点像最短路呢?对于每一个字符串,若它能覆盖的位置是从 i 到 j,那么连一条边i→j+1。
从0~n做最短路,选什么算法随意,当然既然是个DAG,顺序还是固定的,直接DP式地做这个最短路即可。
然后递归输出答案,解决。
 
代码(0.031S):
 #include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std; const int MAXV = ;
const int MAXS = ;
const int MAXL = ;
const int MAXE = MAXS * MAXL; int number[] = {, , , , , , , , , , , , , , , , , , , , , , , , , };
int mat[MAXV][MAXV], pre[MAXV], ecnt, n, k;
int s[MAXS][MAXL], src[MAXV], len[MAXS];
char ans[MAXS][MAXL], str[MAXV]; void init() {
memset(mat, -, sizeof(mat));
} void add_edge(int u, int v, int pos) {
mat[u][v] = pos;
} int dis[MAXV]; bool SPFA() {
memset(dis, 0x3f, sizeof(dis));
dis[] = ;
for(int i = ; i < n; ++i) {
for(int j = i + ; j <= n; ++j) {
if(~mat[i][j] && dis[i] + < dis[j]) {
pre[j] = mat[i][j];
dis[j] = dis[i] + ;
}
}
}
return dis[n] <= n;
} void getFail(int P[], int m, int f[]) {
f[] = f[] = ;
for(int i = ; i < m; ++i) {
int j = f[i];
while(j && P[i] != P[j]) j = f[j];
f[i + ] = (P[i] == P[j] ? j + : );
}
} void KMP(int T[], int n, int P[], int m, int f[], int pos) {
getFail(P, m, f);
for(int i = , j = ; i < n; ++i) {
while(j && P[j] != T[i]) j = f[j];
if(P[j] == T[i]) ++j;
if(j == m) add_edge(i - m + , i + , pos);
}
} void print(int pos) {
if(pos - len[pre[pos]] != ) {
print(pos - len[pre[pos]]);
putchar(' ');
}
printf("%s", ans[pre[pos]]);
} int fail[MAXL]; int main() {
while(scanf("%s", str) != EOF) {
if(strcmp(str, "-1") == ) break;
n = strlen(str);
for(int i = ; i < n; ++i) src[i] = str[i] - '';
scanf("%d", &k);
for(int i = ; i < k; ++i) {
scanf("%s", ans[i]);
len[i] = strlen(ans[i]);
for(int j = ; j < len[i]; ++j) s[i][j] = number[ans[i][j] - 'a'];
}
init();
for(int i = ; i < k; ++i)
KMP(src, n, s[i], len[i], fail, i);
if(SPFA()) print(n), puts("");
else puts("No solution.");
}
}

URAL 1002 Phone Numbers(KMP+最短路orDP)的更多相关文章

  1. 1002 Phone Numbers 解题报告

    1002. Phone Numbers Time limit: 2.0 secondMemory limit: 64 MB In the present world you frequently me ...

  2. 递推DP URAL 1586 Threeprime Numbers

    题目传送门 /* 题意:n位数字,任意连续的三位数字组成的数字是素数,这样的n位数有多少个 最优子结构:考虑3位数的数字,可以枚举出来,第4位是和第3位,第2位组成的数字判断是否是素数 所以,dp[i ...

  3. 递推DP URAL 1009 K-based Numbers

    题目传送门 题意:n位数,k进制,求个数分析:dp[i][j] 表示i位数,当前数字为j的个数:若j==0,不加dp[i-1][0]; 代码1: #include <cstdio> #in ...

  4. ural 2070. Interesting Numbers

    2070. Interesting Numbers Time limit: 2.0 secondMemory limit: 64 MB Nikolay and Asya investigate int ...

  5. ural 1150. Page Numbers

    1150. Page Numbers Time limit: 1.0 secondMemory limit: 64 MB John Smith has decided to number the pa ...

  6. URAL 1056 Computer Net(最短路)

    Computer Net Time limit: 2.0 secondMemory limit: 64 MB Background Computer net is created by consecu ...

  7. URAL 2034 Caravans(变态最短路)

    Caravans Time limit: 1.0 secondMemory limit: 64 MB Student Ilya often skips his classes at the unive ...

  8. URAL 2031. Overturned Numbers (枚举)

    2031. Overturned Numbers Time limit: 1.0 second Memory limit: 64 MB Little Pierre was surfing the In ...

  9. URAL 1012 K-based Numbers. Version 2(DP+高精度)

    题目链接 题意 :与1009一样,不过这个题的数据范围变大. 思路:因为数据范围变大,所以要用大数模拟,用java也行,大数模拟也没什么不过变成二维再做就行了呗.当然也可以先把所有的都进行打表,不过要 ...

随机推荐

  1. linux下线程调用sleep,进程挂起

    http://blog.csdn.net/horstlinux/article/details/7911457 http://blog.csdn.net/eroswang/article/detail ...

  2. Best practice: escape, or encodeURI / encodeURIComponent

    escape() Don't use it, as it has been deprecated since ECMAScript v3. encodeURI() Use encodeURI when ...

  3. 设计模式:策略模式(Strategy)

    定   义:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化, 不会影响到使用算法的客户. 示例:商场收银系统,实现正常收费.满300返100.打8折.......等不同收费 ...

  4. Asp.Net MVC 路由

    原文链接:http://www.asp.net/learn/mvc/ 在这篇教程中,我将为你介绍每个ASP.NET MVC应用程序都具有的一个重要功能,称作ASP.NET路由(ASP.NET Rout ...

  5. 真不知道JavaScrip【数组】还有这么多东西....

    前段时间在频繁的用数组,但一直不知道JavaScript 数组还有这么多东西,收集了一下看看: 首先:数组是对象的特殊形式,接下来看看它有哪些方法.....push()在末尾增加一个或者是多个 uns ...

  6. Web设计者和开发者必备的28个Chrome插件

    摘要 对于许多Web设计者和开发者来说,Firefox浏览器是无法超越的,对于其他人Chrome正在蚕食Firefox的浏览器市场. 在过去的两年,谷歌Chrome浏览器的发布以来,引起了人们激烈争论 ...

  7. iOS WIFI

    一.公共WIFI综述 现在很多公司都在做免费WIFI,车站.公交.地铁.餐厅,只要是人员密集流动的地方就有WIFI,免费WIFI从最初的网页认证方式也逐渐向客户端认证方式偏移.本文主要讨论iOS认证上 ...

  8. Shell数组的增删改查

    Shell数组的增删改查 shell数组的定义及取值: a=(1 2 3) [root@bogon tmp]# echo ${a[*]}  1 2 3 [root@bogon tmp]# echo $ ...

  9. gdb 7.11

    因为CentOS自带的GDB版本有点低,所以下载了最新的gdb 7.11编译以后,调试过程中提示以下错误. Python Exception <type 'exceptions.NameErro ...

  10. Android:学习AIDL,这一篇文章就够了(下)

    前言 上一篇博文介绍了关于AIDL是什么,为什么我们需要AIDL,AIDL的语法以及如何使用AIDL等方面的知识,这一篇博文将顺着上一篇的思路往下走,接着介绍关于AIDL的一些更加深入的知识.强烈建议 ...