题目大意:2到9每个数字对应3字母(对应关系题中已给出),给定一个长度不超过12的数字序列,则可以对应到多个字符串,现给定一个字典(含很多字符串的文件),打印数字序列对应的且在字典中出现过的字符串。
分析:每个数字对应3个字母,最坏情况下有12个数字,可对应312=531441个字符串,而且题中字典中的字符串是按字典序给出的,所以可以用二分查找,所以应该可以用暴力+二分过。另一个办法就是建字典树,然后dfs时边搜遍判断,这样效率应该有所提升。我是用字典树过的。
需要注意的是当字典中不存在符合要求的字符串时,要输出“NONE”
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* ID: lijian42 LANG: C++ TASK: namenum */ #include <stdio.h> #include <string.h> #define N 5001 #define LEN 15 int node; int next[N*LEN][26]; bool isend[N*LEN]; int n; char num[LEN]; char name[LEN]; char table[10][3]; bool success; void add(int cur,int k) { memset(next[node],0,sizeof(next[node])); isend[node]=false; next[cur][k]=node++; } void build() { FILE *fp=fopen("dict.txt","r"); int i,k,cur; char s[LEN]; node=1; memset(next[0],0,sizeof(next[0])); while(~fscanf(fp,"%s",s)) { cur=0; for(i=0;s[i];i++) { k=s[i]-'A'; if(next[cur][k]==0) add(cur,k); cur=next[cur][k]; } isend[cur]=true; } } void init() { int i,j; char c='A'; for(i=2;i<10;i++) { for(j=0;j<3;j++) { table[i][j]=c; c++; if(c=='Q') c++; } } build(); } void dfs(int dep,int cur) { if(dep==n) { name[dep]=0; if(isend[cur]) puts(name),success=true; return; } int i=num[dep]-'0',j,k; for(j=0;j<3;j++) { k=table[i][j]-'A'; if(next[cur][k]==0) continue; name[dep]=k+'A'; dfs(dep+1,next[cur][k]); } } int main() { freopen("namenum.in","r",stdin); freopen("namenum.out","w",stdout); init(); while(~scanf("%s",num)) { n=strlen(num); success=false; dfs(0,0); if(success==false) puts("NONE"); } return 0; }