`

hdu 1298 T9(字典树+dfs)

阅读更多

 T9

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 674    Accepted Submission(s): 271

Problem Description
A while ago it was quite cumbersome to create a message for the Short Message Service (SMS) on a mobile phone. This was because you only have nine keys and the alphabet has more than nine letters, so most characters could only be entered by pressing one key several times. For example, if you wanted to type "hello" you had to press key 4 twice, key 3 twice, key 5 three times, again key 5 three times, and finally key 6 three times. This procedure is very tedious and keeps many people from using the Short Message Service.

This led manufacturers of mobile phones to try and find an easier way to enter text on a mobile phone. The solution they developed is called T9 text input. The "9" in the name means that you can enter almost arbitrary words with just nine keys and without pressing them more than once per character. The idea of the solution is that you simply start typing the keys without repetition, and the software uses a built-in dictionary to look for the "most probable" word matching the input. For example, to enter "hello" you simply press keys 4, 3, 5, 5, and 6 once. Of course, this could also be the input for the word "gdjjm", but since this is no sensible English word, it can safely be ignored. By ruling out all other "improbable" solutions and only taking proper English words into account, this method can speed up writing of short messages considerably. Of course, if the word is not in the dictionary (like a name) then it has to be typed in manually using key repetition again.


Figure 8: The Number-keys of a mobile phone.

More precisely, with every character typed, the phone will show the most probable combination of characters it has found up to that point. Let us assume that the phone knows about the words "idea" and "hello", with "idea" occurring more often. Pressing the keys 4, 3, 5, 5, and 6, one after the other, the phone offers you "i", "id", then switches to "hel", "hell", and finally shows "hello".

Write an implementation of the T9 text input which offers the most probable character combination after every keystroke. The probability of a character combination is defined to be the sum of the probabilities of all words in the dictionary that begin with this character combination. For example, if the dictionary contains three words "hell", "hello", and "hellfire", the probability of the character combination "hell" is the sum of the probabilities of these words. If some combinations have the same probability, your program is to select the first one in alphabetic order. The user should also be able to type the beginning of words. For example, if the word "hello" is in the dictionary, the user can also enter the word "he" by pressing the keys 4 and 3 even if this word is not listed in the dictionary.

 

 

Input
The first line contains the number of scenarios.

Each scenario begins with a line containing the number w of distinct words in the dictionary (0<=w<=1000). These words are given in the next w lines. (They are not guaranteed in ascending alphabetic order, although it's a dictionary.) Every line starts with the word which is a sequence of lowercase letters from the alphabet without whitespace, followed by a space and an integer p, 1<=p<=100, representing the probability of that word. No word will contain more than 100 letters.

Following the dictionary, there is a line containing a single integer m. Next follow m lines, each consisting of a sequence of at most 100 decimal digits 2-9, followed by a single 1 meaning "next word".

 

Output
The output for each scenario begins with a line containing "Scenario #i:", where i is the number of the scenario starting at 1.

For every number sequence s of the scenario, print one line for every keystroke stored in s, except for the 1 at the end. In this line, print the most probable word prefix defined by the probabilities in the dictionary and the T9 selection rules explained above. Whenever none of the words in the dictionary match the given number sequence, print "MANUALLY" instead of a prefix.

Terminate the output for every number sequence with a blank line, and print an additional blank line at the end of every scenario.

 

Sample Input
2 5 hell 3 hello 4 idea 8 next 8 super 3 2 435561 43321 7 another 5 contest 6 follow 3 give 13 integer 6 new 14 program 4 5 77647261 6391 4681 26684371 77771

 

Sample Output
Scenario #1: i id hel hell hello i id ide idea Scenario #2: p pr pro prog progr progra program n ne new g in int c co con cont anoth anothe another p pr MANUALLY MANUALLY
 
            题目大意:先给出你几个单词的按键频数,然后给出你输入的数字,按这些数字的输入来输出最高频数的单词,没有就输出MANUALLY。

           这题是一道很好的字典树,一个模拟手机输入法的算法,要用到深搜来解决输出哪个频数最多的单词。第一次写,写了很长时间,现在看回来,发现不过如此,链表不是很熟悉,要多写多练习才行啊!

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1298

代码:

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <string>
using namespace std;

char map[10][5];
char res[105], str[105];
int MAX;

void set()  //定义map[][]
{
    strcpy(map[0], "");
    strcpy(map[1], "");
    strcpy(map[2], "abc");
    strcpy(map[3], "def");
    strcpy(map[4], "ghi");
    strcpy(map[5], "jkl");
    strcpy(map[6], "mno");
    strcpy(map[7], "pqrs");
    strcpy(map[8], "tuv");
    strcpy(map[9], "wxyz");
}

struct node     //结点结构
{
    int val;            //频率
    char ch[105];       //字符
    node *next[26];     //链表
};

node *root, memory[100005];
int cnt;

node* create()
{
    node *p = &memory[cnt++];
	p->val = 0;
    int i;
    for(i = 0; i < 26; i++)
    {
        p->next[i] = NULL;
    }
    return p;
}

void insert(char *s, int val)
{
    node *p = root;
    char str[105];
    int i, k;
    for(i = 0; s[i]; i++)
    {
        k = s[i] - 'a';
        if(p->next[k] == NULL)
        {
            p->next[k] = create();
        }
        p = p->next[k];
        p->val += val;      //结点频率相加
        str[i] = s[i];
        str[i+1] = 0;
        strcpy(p->ch, str); //结点保存该点的字符串
    }
}

void dfs(node *p, int cur, int op)    //深搜字典树(结点,当前位置,目标)
{
    if(cur == op)   //当前位置 == 目标位置
    {
        if(p->val > MAX)    //找频率最大的那个字符串
        {
            strcpy(res, p->ch);
            MAX = p->val;
        }
        return;
    }
    int i, k, l, len;
    k = str[cur+1] - '0';       //char数字->int数字
    len = strlen(map[k]);       //map[k]为k键包含的字符
    for(i = 0; i < len; i++)
    {
        l = map[k][i] - 'a';    //将字符->整型
        if(p->next[l] == NULL) continue;    //若为空,continue
        else dfs(p->next[l], cur+1, op);    //否则,继续深搜
    }
}

int main()
{
    int i, t, n, m, val, len, zz = 1;
    char sh[105];
    set();
    scanf("%d", &t);
    while(t--)
    {
        memset(memory, NULL, sizeof(memory));
        cnt = 0;
        root = create();
        scanf("%d", &n);
        for(i = 0; i < n; i++)
        {
            scanf("%s %d", sh, &val);
            insert(sh, val);    //将字符串插入字典树中
        }
		printf("Scenario #%d:\n", zz++);
        scanf("%d", &m);
        while(m--)
        {
            scanf("%s", str);
            len = strlen(str);
            for(i = 0; str[i] != '1'; i++)
            {
                MAX = -1;
                dfs(root, -1, i);
                if(MAX != -1) printf("%s\n", res);
                else printf("MANUALLY\n");
            }
			if(m != 0) printf("\n");
        }
        printf("\n\n");
    }

    return 0;
}

 

 

 

        

  • 大小: 4.6 KB
2
10
分享到:
评论
2 楼 gzhu_101majia 2011-10-04  
  
1 楼 基德KID.1412 2011-10-04  
我特么顶上!!  

相关推荐

    HDU+2000-2099+解题报告

    HDU(杭州电子科技大学)在线评测系统是许多编程竞赛爱好者和学习者经常访问的平台,它提供了大量的算法题目供用户练习和挑战。这个压缩包文件“HDU 2000-2099 解题报告”显然包含了在这个题号范围内的一些问题、...

    hdu 3341(ac自动机+状态压缩)

    hdu 3341(ac自动机+状态压缩) 题意:容易理解... 思路:首先一开始容易想到要用到dp,开设一个dp[41][41][41][41][501]的数组来解决,但是明显内存已经超出范围了,于是就想如何减少内存呢?只要知道A、T、C、G其中...

    HDU+2000-2099+解题报告.zip

    《杭电OnlineJudge 2000-2099解题报告》是针对杭州电子科技大学(HDU)在线评测系统(OnlineJudge)中2000至2099题目的详细解答集锦,主要涵盖了算法分析、编程技巧以及问题解决策略等内容。这份解题报告以CHM...

    ACM hdu 线段树题目+源代码

    ACM hdu 线段树题目+源代码 线段树是一种非常重要的数据结构,它广泛应用于算法竞赛和实际编程中。今天,我们将通过 ACM hdu 的几个题目来学习和掌握线段树的基本概念和应用。 线段树的基本概念 线段树是一种...

    hdu acm1166线段树

    hdu 1166线段树代码

    HDU刷题地图+精选详细笔记

    本人准备2020年保研机试时刷的题目(虽然最后机试取消了,...来自某中流985,在HDU和vjudge平台上大概刷了400道。本文件地图(excel表格)包含了绝大部分我刷过的题目,笔记中具有思路、代码、总结和心得。 大佬勿入!

    hdu 1695 GCD(欧拉函数+容斥原理).docx

    "hdu 1695 GCD(欧拉函数+容斥原理)" 题目大意是:给定 a, b, c, d, k,找到一队 x, y,满足 g(x, y) = k,且 x ∈ [1, b], y ∈ [1, d],问有多少对符合要求的 (x, y)。 思路是:gcd(x, y) == k 解释 x, y 都能...

    hdu 1753 大明A+B

    Problem Description 话说,经过了漫长的一个多月,小明已经成长了许多,所以他改了一个名字叫“大明”。 这时他已经不是那个只会做100以内加法的那个“小明”了,现在他甚至会任意长度的正小数的加法。...

    hdu 300+ AC 代码

    HDU 300+ AC 代码集合是一个包含超过300个已通过验证的算法解决方案的资源,这些代码主要用于解决各类计算机编程竞赛中的问题。这些竞赛通常由杭州电子科技大学(HDU)主办,旨在提升参赛者的算法设计、编程和问题...

    hdu.rar_hdu

    3. **数据结构**:数组、链表、栈、队列、树(二叉树、平衡树如AVL和红黑树)、图(邻接矩阵、邻接表、最小生成树、拓扑排序等)。 4. **字符串处理**:KMP算法、Manacher's Algorithm、Rabin-Karp算法等。 5. **...

    HDU ACM as easy as a+b

    - **HDU** 指的是“杭州电子科技大学”(Hangzhou Dianzi University),这所大学在ACM国际大学生程序设计竞赛中有着优异的表现。 - **ACM** 是指“Association for Computing Machinery”,即计算机协会,而在此处...

    HDU题目java实现

    8. **图论与树**:HDU题目中可能涉及图的遍历(深度优先搜索DFS、广度优先搜索BFS)、树的遍历(前序、中序、后序)以及最小生成树、最短路径等算法。 9. **动态规划**:这是一种优化策略,通过构建状态转移方程来...

    解题代码 hdu1241

    DFS是一种用于遍历或搜索树或图的算法。在这个过程中,算法从根节点开始探索尽可能深的子节点路径。当到达最深的叶子节点时,它会回溯到最近的一个未完成探索的节点,并继续进行探索。 **实现方法:** DFS通常有两...

    HDU_2010.rar_hdu 2010_hdu 20_hdu acm20

    【标题】"HDU_2010.rar"是一个压缩包文件,其中包含了与"HDU 2010"相关的资源,特别是针对"HDU ACM20"比赛的编程题目。"hdu 2010"和"hdu 20"可能是该比赛的不同简称或分类,而"hdu acm20"可能指的是该赛事的第20届...

    hdu 1166线段树

    标题与描述均提到了“hdu 1166线段树”,这表明文章的核心是关于线段树在解决特定问题中的应用。线段树是一种数据结构,主要用于处理区间查询和更新操作,尤其是在大规模数据集上。在本例中,通过分析给定的部分代码...

    二叉搜索树练习 HDU3791

    总结来说,"二叉搜索树练习 HDU3791"是一道关于二叉搜索树操作的编程题,可能需要实现插入、删除、查找等基本操作,并通过分析`Main.java`源码来理解和解决问题。同时,可能需要借助各种工具进行调试和测试,以确保...

    ACM HDU题目分类

    ACM HDU 题目分类 ACM HDU 题目分类是指对 HDU 在线判题系统中题目的分类,总结了大约十来个分类。这些分类将有助于编程选手更好地理解和解决问题。 DP 问题 DP(Dynamic Programming,动态规划)是一种非常重要...

    hdu1250高精度加法

    ### hdu1250高精度加法 #### 背景介绍 在计算机科学与编程竞赛中,处理大整数运算(特别是加法、减法、乘法等)是常见的需求之一。当数字的位数超过了标准数据类型(如`int`、`long`等)所能表示的最大值时,就需要...

    hdu acm 教案(7)

    1. **深度优先搜索(DFS, Depth-First Search)**:DFS是一种遍历或搜索树(或图)的算法,它沿着树的深度方向进行探索,直到达到叶子节点或者回溯到一个未被访问的分支。DFS通常用于解决连通性问题,如判断图是否...

    acm入门之枚举搜索

    acm入门之枚举搜索,学校第一次acm培训,包括枚举及其优化,dfs和bfs

Global site tag (gtag.js) - Google Analytics