zoukankan      html  css  js  c++  java
  • 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:
    ",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
    ",e);
                    else printf("MANUALLY
    ");
                }
                printf("
    ");
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    CoreData和SQLite多线程访问时的线程安全问题
    JSPatch 实现原理详解
    iOS开发工程师必备技能(持续更新)
    iOS音频播放、录音、视频播放、拍照、视频录制
    使用MVVM减少控制器代码实战(减少56%)
    如何结合场景利用block进行回调
    Masonry框架源码深度解析
    Ubantu编译安装FFmpeg
    HTTP Live Streaming网络视频直播调研
    RHEL/CentOS 6的更新源
  • 原文地址:https://www.cnblogs.com/dashuzhilin/p/4503600.html
Copyright © 2011-2022 走看看