题意:给你一些固定的字符串,在给出数字,根据键盘的对应关系,输出所有的满足条件的字符串,输出顺序无所谓。
思路:因为题目说了,输出比较小,说明测试数据并不强,所以可以暴力回溯求出答案,将所有的给出的字符串压缩为数字,再将对应相同数字的字符串存储起来(当时忘了这里,WA了几次),然后深搜即可。
注意:多个字符串有可能对应相同的数字,需要另外存储,在深搜的时候,枚举这个符合条件的字符串。
代码如下:
#include<iostream> #include<cstdio> #include<vector> #include<cstring> #include<map> #include<cmath> using namespace std; map<string,int>ma; vector<int> ve[150]; char get_num(char ch){ if(ch>='a'&&ch<='c') return '2'; if(ch>='d'&&ch<='f') return '3'; if(ch>='g'&&ch<='i') return '4'; if(ch>='j'&&ch<='l') return '5'; if(ch>='m'&&ch<='o') return '6'; if(ch>='p'&&ch<='s') return '7'; if(ch>='t'&&ch<='v') return '8'; if(ch>='w'&&ch<='z') return '9'; } string change(string a){ int len = a.length(); string tmp = ""; for(int i = 0;i < len;i++){ tmp += get_num(a[i]); } return tmp; } string word[150]; char aim[330]; int len; string ans[150]; void dfs(int id,int num){ if(id == len){ for(int i = 0;i < num;i++){ if(i==0) cout<<ans[i]; else cout<<" "<<ans[i]; } cout<<"."<<endl; return ; } string tmp = ""; int lenv,mtmp,vnum; for(int i = id;i < len;i++){ tmp += aim[i]; mtmp = ma[tmp]; if(mtmp){ lenv = ve[mtmp].size(); for(int j = 0;j < lenv;j++){ vnum = ve[mtmp][j]; ans[num] = word[vnum]; dfs(i+1,num+1); ans[num] = ""; } } } return ; } int main() { int n,tmp,vis[150]; string changed[150]; //freopen("D.in.cpp","r",stdin); while(~scanf("%d",&n)){ if(!n) break; ma.clear(); for(int i = 1;i <= n;i++){ cin>>word[i]; changed[i] = change(word[i]); ma[changed[i]] = i; ve[i].clear(); } memset(vis,0,sizeof(vis)); for(int i = 1;i <= n;i++){ if(vis[i]) continue; tmp = ma[changed[i]]; for(int j = i;j <= n;j++){ if(changed[i] == changed[j]){ vis[j] = 1; ve[tmp].push_back(j); } } } scanf("%s",aim); len = strlen(aim); dfs(0,0); printf("-- "); } return 0; }