题目大意:一道模拟手机输入法的题目,输入每个单词以及出现的频率,最后给你一串数字代表用户输入的,按照长度足够输出显示的单词。
思路:根据单词建立字典树,然后对于每个长度进行dfs找到最大频率的单词。
#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
using namespace std;
char map[][12]={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
int maxx;
char res[123],ans[123];
struct trie
{
int pl;
trie *next[27];
char ch[123];
};
trie *root;
void init(char *v,int m)
{
int i;
char st[123];
trie *p=root,*q;
for(i=0;v[i];i++)
{
int k=v[i]-'a';
if(p->next[k]==NULL)
{
q=(trie *)malloc(sizeof(trie));
q->pl=0;
q->ch[0]='\0';
for(int j=0;j<26;j++) q->next[j]=NULL;
p->next[k]=q;
}
p=p->next[k];
p->pl+=m;
st[i]=v[i];
st[i+1]='\0';
strcpy(p->ch,st); //小技巧,存到当前节点的单词。
}
}
void dfs(trie *p,int x,int ed) // dfs遍历长度为ed的所有单词,找出最大的。
{
if(x==ed) //满足长度
{
if(p->pl>maxx) //寻找最大频率的单词。
{
maxx=p->pl;
strcpy(res,p->ch);
}
return;
}
int i=x+1,j;
i=ans[i]-'0';
for(j=0;map[i][j];j++) //遍历当前数字所对应的字母
{
int k=map[i][j]-'a';
if(p->next[k]!=NULL) dfs(p->next[k],x+1,ed);
}
return ;
}
void del(trie *p)
{
for(int i=0;i<26;i++) if(p->next[i]!=NULL) del(p->next[i]);
free(p);
}
int main()
{
int t,cas=1;
cin>>t;
while(t--)
{
int n;
scanf("%d",&n);
root=(trie *)malloc(sizeof(trie));
root->pl=0;
for(int j=0;j<26;j++) root->next[j]=NULL;
while(n--)
{
char v[123];
int m;
scanf("%s%d",v,&m);
init(v,m);
}
scanf("%d",&n);
printf("Scenario #%d:\n",cas++);
while(n--)
{
int i;
scanf("%s",ans);
for(i=0;ans[i+1];i++)
{
maxx=-1;
dfs(root,-1,i); //若maxx为-1代表没有单词了
puts(maxx==-1?"MANUALLY":res);
}
puts("");
}
puts("");
del(root);
}
}