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