HDU 1298 T9(字典树+搜索)

题意:每组有n个字符串,每个串对应一个权值,给出一个手机按键表,每个数字键可对应按出几个字母,m个询问,给出一串数字(最后一位不计),求该数字串对应的权值最大的字符串(将数字串每个前缀对应的字符串输出);

思路:将n个字符串插入字典树,在串的查询操作上进行深搜以便更新最大值,并且每个数字对应几个字符,分别遍历一下。经典题。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
    int num;
    node *next[26];
};
node *head;
int phone[8][4]={{0,1,2},{3,4,5},{6,7,8},{9,10,11},{12,13,14},{15,16,17,18},{19,20,21},{22,23,24,25}};//每个数字键对应的字母
int re[8]={3,3,3,3,3,4,3,4};//一个数字键包含的字母数
void init(node *h)
{
    for(int i=0;i<26;i++)
    {
        h->next[i]=NULL;
        h->num=0;
    }
}
int p;
char str[500010];
char ch[500010],ans[500010],e[500010];
void h_insert(char s[],int d)
{
    node *t,*s1=head;
    int n=strlen(s);
    for(int i=0;i<n;i++)
    {
        int k=s[i]-'a';
        if(s1->next[k]==NULL)
        {
            t=new node;
            init(t);
            s1->next[k]=t;
        }
        s1=s1->next[k];
        s1->num+=d;
    }
}
void dfs(node *h,int now,int len)
{
    if(now==len)
    {
        if(p<h->num)//更新为权值最大的匹配串
        {
            p=h->num;
            for(int i=0;i<len;i++)
            e[i]=ans[i];
           // e[len]=0;//小技巧
        }
        return;
    }
    int t=ch[now]-'2';
    for(int i=0;i<re[t];i++)
    {
        int d=phone[t][i];
        if(h->next[d])
        {
           ans[now]='a'+d;
           dfs(h->next[d],now+1,len);
        }
    }
    return;
}
int main()
{
    int t,n,i,j,k,m,len,cas;
    scanf("%d",&t);
    for(cas=1;cas<=t;cas++)
    {
        printf("Scenario #%d:\n",cas);
        memset(e,0,sizeof(e));
        memset(ans,0,sizeof(ans));
        memset(str,0,sizeof(str));
        memset(ch,0,sizeof(ch));
        head=new node;
        init(head);
        scanf("%d",&n);
        while(n--)
        {
            scanf("%s %d",str,&k);
            h_insert(str,k);
        }
        scanf("%d",&m);
        while(m--)
        {
            scanf("%s",ch);
            len=strlen(ch);
            memset(e,0,sizeof(e));
            for(i=1;i<len;i++)
            {
                p=0;
                node *temp=head;
                dfs(temp,0,i);//枚举前缀,逐个查询
                if(p>0) printf("%s\n",e);
                else printf("MANUALLY\n");
            }
            printf("\n");
        }
        printf("\n");
    }
    return 0;
}

 

posted on 2015-05-14 16:08  大树置林  阅读(149)  评论(0编辑  收藏  举报

导航