HDU 1298 T 9(携帯電話の入力方法に関するもので、辞書ツリー+dfs)


リンク:
http://acm.hdu.edu.cn/showproblem.php?pid=1298
タイトル:
Problem Description
A while ago it was quite e cumberssome to create a message for the ShotMessage Service(SMS)on a mobile phone.Thiswas because e e e e e ninininive keys and the alesfeaaaate has mothnine nine letters、sosomomost eeeeeemimimimimie e e e e e e e e e e e e e e e e e e e e e e enine leletterse e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e press key 4 twice、key 3 twice,key 5 three times,again key 5 three times,and finally key 6 three times.This procedue is very tedious and keeps many people from use the Shot Message Service.
This led manufactures of mobile phones to try and find an ease way to nter text on a mobile phone.The solution they developed is caled T 9 text input.The"9"私たちのためには、私たちのためには、お客様のお得なお得なお得なお得なお得なお得なお得なお得なお得なお得なお得なお得なお得なお得なお得なお得なのです.イベント"hello"you simply press keys 4,3,5,5,and 6 once.Of course,this could also be the input for the the word"gdjm"は、but since thisのsensible English word,it can safelybe Ignored.Prote.「solutions and only Taning proper English words in to account、this method can speed up writing of Shot message s considers able.Of course、if the word is not in the dictorary(like a name)the the the n hars the the the the it the the has typenight typemation)the typeingmant typeingmation.
HDU 1298 T9(手机输入法相关,字典树+dfs)_第1张图片
Figure 8:The Number-keys of a mobile phone.
More precisely,with evevrycharacter typed,the phone will showthe most probable combination of characters it has found up to that point.Let us asume the phone knows aout the wods「ida」and「helle」,thethethethethethethethethethe fififie e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e thethethethethethethethererererererererererererererereree e e e e e e e e e eあなた「i」「id」then switch to「hel」、「hell」、and finally shows「hello」.
Write an implemenation of the T 9 text input whifers the most probable charactr coracter coracter combination affterevevininininininininininininininininststststininininininininininststststininininininininininininininininstststststststininininininininininininininininininininininstststststststststststststststststinininininininininininininininininininininininininininininininininininininininininininininin「hello」、and「hellfire」、the probability of the character cobination「hell」is the sum of the probabilies of thers worss.If some commations have the same probability、your program is to select the first the abersone aborsons.the ables.The aborsons.「is in the dictionary,the user can also enter the word」he「by pressing the keys 4 and 3 even if word is not listed in the dictionary.
 
Input
The first line contains the number of scenaros.
Each scenaro begins with a line containinining the number w of distinctwods in the didictininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininststststststinininininininininininininininininininininininctarararararararararararararary(0 didididididictararararararararary(0==========================w dededededethout whitess pace,フォロワーby a space and an integer p,1<=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 follows m lines,each consisting of a sequence of at most 100 decimal digits 2-9,followd by a single 1 meaning“next word”.
 
Output
The output for each scenaro begins with a line containing「Scienaro龛i:」、where i is the number of the scenaro starting at 1.
For evrynumber sequence s of the scenaro、print one inininininininininstored stored inins、except for the 1 at the end.In this line、prntthe most probable wod prefiefined bythe probabiinininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininprint「MANUALLY」instead of a prefix.
Terminate the output for everry number sequence with a blank line、and print an additional blank line、the end of everscenaro.
 
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
 
タイトルの大意:
以前は携帯の入力が面倒くさいです.9つのキーしかないので、26文字です.一つのキーにこれらの文字が同時に含まれています.このようにすると、一つの文字を打つためには何回か押すことができます.例えば、キー5に「JKL」があります.Kを入力するなら、続けて二回押します.
このような入力方法は面倒くさいです.だから、ある会社はT 9技術の入力法を発明しました.このような入力法には多くの英語の単語が内蔵されています.英語の出現頻度によって、存在するかどうかなどの情報があります.各文字は一回押すだけで、希望の予備単語があります.
例えば、入力方法が一つの単語「hell」だけを内蔵していると仮定すれば、4355を押すだけで出てきます.
注意してください.hellという単語があるなら、この単語のすべてのプレフィックス、h、he、helも存在しているものとみなされます.
分析とまとめ:
この問題は実際の応用と関係があるようです.
必要に応じて辞書の木を作って、単語を挿入する時、一緒に降りても周波数pを加えます.
そしてdfsを使って、最大の頻度の単語を求めて出力します.
この問題をする時、意外にも1 Aになりました.笑って死にます.
コード:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;

const int KIND = 26;
const int MAXN = 15000;
int cnt_node;

vector<int>g[10];
char input[105];
char ans[105];
int num, Max;
bool flag;

struct node{
    int prefix;
    node *next[KIND];
    void init(){
        prefix=0;
        memset(next, 0, sizeof(next));
    }
}Heap[MAXN];

inline node* newNode(){
    Heap[cnt_node].init();
    return &Heap[cnt_node++];
}
void insert(node *root, char *str, int n){
    for(char *p=str; *p; ++p){
        int ch=*p-'a';
        if(root->next[ch]==NULL)
            root->next[ch] = newNode();
        root = root->next[ch];
        root->prefix += n;
    }
}
void dfs(node *root, char *str, int pos){ //str      
    if(root==NULL)return;
    if(pos >= num){
        if(root->prefix > Max){
            strcpy(ans, str);
            Max=root->prefix;
        } 
        flag=true;
        return ;
    }
    int u=input[pos]-'0';
    for(int i=0; i<g[u].size(); ++i){
        str[pos] = g[u][i]+'a';
        dfs(root->next[g[u][i]], str, pos+1);
        str[pos] = 0;
    }
}

int main(){
    int T,n,p,cas=1;
    char str[105];

    //     ,         ...
    for(int i=0; i<10; ++i) g[i].clear();
    g[2].push_back(0), g[2].push_back(1), g[2].push_back(2);
    g[3].push_back(3), g[3].push_back(4), g[3].push_back(5);
    g[4].push_back(6), g[4].push_back(7), g[4].push_back(8);
    g[5].push_back(9), g[5].push_back(10), g[5].push_back(11);
    g[6].push_back(12), g[6].push_back(13), g[6].push_back(14);
    g[7].push_back(15), g[7].push_back(16), g[7].push_back(17),g[7].push_back(18);
    g[8].push_back(19), g[8].push_back(20), g[8].push_back(21);
    g[9].push_back(22), g[9].push_back(23), g[9].push_back(24), g[9].push_back(25);

    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        printf("Scenario #%d:
", cas++); // Trie init cnt_node=0; node *root = newNode(); for(int i=0; i<n; ++i){ scanf("%s %d",str,&p); insert(root, str, p); } scanf("%d",&n); for(int i=0; i<n; ++i){ scanf("%s", input); for(int j=0; j<strlen(input)-1; ++j){ memset(str, 0, sizeof(str)); Max=-1; num=j+1; flag=false; dfs(root, str, 0); if(flag) puts(ans); else puts("MANUALLY"); } puts(""); } puts(""); } return 0; }

   
    

——   , 。

          
       http://blog.csdn.net/shuangde800 , By   D_Double  ( )