题意:就是让你模拟手机输入单词。具体就是给你一些单词,以及该单词被使用的频数,这个频数也是该单词前缀的使用频数,当然不同的单词有可能有相同的前缀,那么这个相同的前缀的使用频数就是这两个单词使用频数之和,以此类推。然后再给你一些数字串,让你针对该数字串的每一个前缀输出它的最有可能对应的单词(即频数最大的字符串)。
解题思路:这道题目比我想象中的简单,直接dfs去搜,因为每个键的字母个数不超过5,所以不会TLE。。。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
struct node *next[26];
int p;
node()
{
p = 0;
for(int i = 0; i < 26; i++)
next[i] = NULL;
}
};
int n,pro;
char s[100],keyboard[10][5]={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
char ans[100],tmp[100];
void add(char *str,int cnt,node *root)
{
node *t = root;
for(int i = 0; str[i] != 0; i++)
{
if(t->next[str[i]-'a'] == NULL)
{
t->next[str[i]-'a'] = new node();
}
t = t->next[str[i]-'a'];
t->p += cnt;
}
}
void dfs(int x,int pos,node *r)
{
int num = s[pos] - '0';
int len = strlen(keyboard[num]);
for(int i = 0; i < len; i++)
{
int t = keyboard[num][i] - 'a';
if(r->next[t] == NULL) continue;
else tmp[pos] = keyboard[num][i];
if(pos == x)
{
if(pro < r->next[t]->p)
{
pro = r->next[t]->p;
strcpy(ans,tmp);
}
}
else dfs(x,pos+1,r->next[t]);
}
}
int main()
{
int t,p,cas = 1;
node *root;
scanf("%d",&t);
while(t--)
{
root = new node();
scanf("%d",&n);
for(int i = 1; i <= n; i++)
{
getchar();
scanf("%s %d",s,&p);
add(s,p,root);
}
printf("Scenario #%d:\n", cas++);
scanf("%d",&n);
for(int i = 1; i <= n; i++)
{
getchar();
scanf("%s",s);
int len = strlen(s);
for(int j = 0; j < len-1; j++)
{
memset(tmp,0,sizeof(tmp));
pro = 0;
dfs(j,0,root);
if(pro == 0)
printf("MANUALLY\n\n");
else printf("%s\n\n",ans);
}
}
}
return 0;
}