poj 1451 || hdu 1298 T9

题目大意:一道模拟手机输入法的题目,输入每个单词以及出现的频率,最后给你一串数字代表用户输入的,按照长度足够输出显示的单词。

思路:根据单词建立字典树,然后对于每个长度进行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);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值