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;
}
时间: 2024-10-07 20:01:25

HDU 1298 T9(字典树+搜索)的相关文章

hdu 1298 T9(字典树+DFS)

题目连接:hdu 1298 T9 题目大意:模拟手机打字的猜想功能,根据概率,每按一个按键,输出可能性最高的串.先给定N个单词,以及频率, 然后是Q次询问,每次询问给定一个按按键的顺序,以1为终止. 解题思路:对单词表建立字典树,每个节点有一个经过的频率,这个频率是根据所有经过该节点的单词频率总和.然后 DFS搜索一遍,将答案保存在ans中. #include <cstdio> #include <cstring> #include <algorithm> using

HDU 1298 T9 ( 字典树 )

题意 : 给你 w 个单词以及他们的频率,现在给出模拟 9 键打字的一串数字,要你在其模拟打字的过程中给出不同长度的提示词,出现的提示词应当是之前频率最高的,当然提示词不需要完整的,也可以是 w 个单词出现最多次数的前缀. 分析 : 利用字典树存储这 w 个单词,然后给每一个结点的权值赋上其单词出现频率,接下来的工作就简单多了,只要暴力枚举模拟输入的数字键盘可能产生的单词组合,然后保存频率最高的那个即可! #include<string.h> #include<stdio.h> #

hdu 2846 Repository 字典树

// hdu 2846 Repository 字典树 // // 题目大意: // // 有n个字符串,m个待询问的字符串,问这些字符串里面以该询问的 // 字符串为子串的字符串有多少个 // // 解题思路: // // 字典树,将字符串的所有子串插入到字典树中,并设立一个No.标识 // 以免重计数.最后查询就好了 // // 感悟: // // 这题的数据量有点大,虽然p是10000,但是长度是20,单个字符串的 // 最大子串数粗略的估计是 20 * 20 ,所以开的空间也要比较大.开始

HDU 1247 简单字典树

Hat’s Words Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7359    Accepted Submission(s): 2661 Problem Description A hat’s word is a word in the dictionary that is the concatenation of exactly

POJ 1451 T9 字典树+优先队列

题目来源:POJ 1451 T9 题意:给你一些单词 和优先值 然后当你按下数字的时候首先会出现哪个单词 就是我们平时手机的按键 思路:建一颗字典树 因为按一个数字对应多个字母 那么就有多种情况 我们要输出权值最大的一个 我用了优先队列 这里每个前缀的优先值是所有单词优先值的和 例如abc 5 abd 6 acd 7 那么a这个前缀的优先值是18 ab的优先值是11 #include <cstdio> #include <cstring> #include <queue>

HDU 2846 Repository(字典树,标记)

题目 字典树,注意初始化的位置~!!位置放错,永远也到不了终点了org.... 我是用数组模拟的字典树,这就要注意内存开多少了,,要开的不大不小刚刚好真的不容易啊.... 我用了val来标记是否是同一个串分解而来的,保存的是串的编号 num记录数目. //string &replace(iterator first0, iterator last0,const_iterator first, const_iterator last); //把[first0,last0)之间的部分替换成[firs

HDU 1298 T9【字典树】

任意门:http://acm.hdu.edu.cn/showproblem.php?pid=1298 T9 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3917    Accepted Submission(s): 1415 Problem Description A while ago it was quite cumbersome

HDU 1298 T9(字典树+dfs)

http://acm.hdu.edu.cn/showproblem.php?pid=1298 题意:模拟手机9键,给出每个单词的使用频率.现在给出按键的顺序,问每次按键后首字是什么(也就是要概率最大的). 思路: 先建立字典树算出每个前缀出现的概率,然后dfs每种情况,选择概率大的. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 const int

hdu 1979 DFS + 字典树剪枝

http://acm.hdu.edu.cn/showproblem.php?pid=1979 Fill the blanks Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 373    Accepted Submission(s): 155 Problem Description There is a matrix of 4*4, yo