题目描述
电话机上每一个数字下面都写了若干个英文字母。分布如下:
1~abc
2~def
3~ghi
4~jkl
5~mn 6~opq
7~rst
8~uvw
9~xyz
现在给定一个单词表和一串数字密码,请你用单词表中的单词翻译这个密码。
输入格式
第一行为一个正整数N表示单词表中单词的个数(N≤100);
第二行为一个长度不超过100的数字串,表示密码;
接下来的N行,每行一个长度不超过20的单词,表示单词表。
输出格式
仅一行,表示翻译后的原文,如果密码无法翻译,则输出“No Solutions!”,如果密码有多种翻译方式,则输出任意一种即可。
输入输出样例
输入 #1复制
8
73373711664
thi
shs
this
is
b
a
boo
k
输出 #1复制
thi shs b boo k
说明/提示
仅一行,表示翻译后的原文,如果密码无法翻译,则输出“No Solutions!”,如果密码有多种翻译方式,则输出任意一种即可。
由@zhouyonglong提供SPJ
上代码:
#include<cstdio>
#include<cstdlib>
#include "memory.h"
#define MAXN 110
using namespace std;
const char st[26]={1,1,1,2,2,2,3,3,3,4,4,4,5,5,6,6,6,7,7,7,8,8,8,9,9,9};
struct trie
{
int end;
trie *son[17];
inline trie();
}mmp[MAXN*MAXN],*mtp=mmp,*head=NULL;
char str[MAXN][MAXN],a[MAXN],b[MAXN];
int ans[MAXN],cnt=0,n=0;
inline void read(int&);
void write(const int&);
inline void insert(char*,const int&);
inline void init(char*);
void dfs(int);
inline void out();
int main()
{
register int i=0;
head=++mtp;
scanf("%d",&n);
scanf("%s",a);
for(i=0;a[i];a[i++]^=48);
for(i=1;i<=n;++i)
{
scanf("%s",str[i]);
}
for(i=1;i<=n;++i)
{
init(str[i]);
if(*b)insert(b,i);
}
dfs(0);
printf("No Solutions!");
return 0;
}
inline trie::trie()
{
end=0;
memset(son,0,sizeof(son));
return;
}
inline void out()
{
register int i=0;
for(i=1;i<cnt;++i)
{
printf("%s ",str[ans[i]]);
}
printf("%s",str[ans[cnt]]);
exit(0);
}
void dfs(int x)
{
register trie *p=head;
for(;a[x];)
{
if(p->end)
{
ans[++cnt]=p->end;
dfs(x);
--cnt;
}
if(p->son[a[x]])
{
p=p->son[a[x]];
++x;
}
else
{
return;
}
}
if(p->end)
{
ans[++cnt]=p->end;
out();
}
return;
}
inline void init(char *a)
{
register int i=0;
for(;*a;++i,++a)
{
b[i]=st[*a-'a'];
}
b[i]='\0';
return;
}
inline void insert(char *a,const int &id)
{
register trie *p=head;
for(;*a;++a)
{
if(p->son[*a])
{
p=p->son[*a];
}
else
{
p=p->son[*a]=++mtp;
}
}
p->end=id;
return;
}