T9
Time Limit: 2000/1000 MS (Java/others) memory limit: 65536/32768 K (Java/Others)
Total submission (s): 629 accepted submission (s): 250
Problem descriptiona 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 cocould 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 contains 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 cocould 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 "El ", "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 shoshould 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.
Inputthe 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 ".
Outputthe 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, blocks t 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 input2
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 outputscenario #1:
I
ID
El
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 is a super disgusting question. I wrote a full plus one day .... There was a sound in the distance, "the level is not good !" You must complete a smart selection system, that is, automatically match the word combination with the highest probability by pressing the keyboard. The solution to this question is basically like this. First, all the words are input into the dictionary tree, which can greatly speed up the search and then the search process, the length of each key will start from the first trigger. because the number of words is small, it is foreseeable that the number of searches is not very large. The selection is based on the weight. Another important step in the search process is to record your search path, that is, keep your best path, this can be achieved through a stack. The previous steps are basically the same, but I didn't record the search path during the search. To reduce the difficulty of the code, I chose to keep the word of each vertex in the node information, in this way, the information in the optimal node can be called up. The Code is as follows:
# Include <stdio. h> # include <stdlib. h> # include <string. h> typedef struct node {int best [10], Val, I; // best is not applied to struct node * child [26];} node; int search [10] [2] = {{}, {}, {0, 2}, {3, 5}, {6, 8}, {9, 11 }, {12, 14}, {15, 18}, {19, 21}, {22, 25 }}; char word [1005] [105]; node * cmpa; node * Init () {node * n = (node *) malloc (sizeof (node); N-> val = 0; n-> I =-1; for (INT I = 0; I <10; ++ I) // Corresponding key initialization {n-> Best [I] =-1; // because '0' represents the branch of a} memset (n-> child, null, sizeof (n-> child); // empty return N;} void insert (node * P, char * In, int Val, int I) // insert operation {If (* In = '\ 0') {return; // For the moment, it is not counted whether the point has a word ending} else {If (p-> child [* In-'a'] = NULL) {// if this branch does not exist, add a new one, that is, the word p-> child [* In-'a'] = Init () with the same prefix is not displayed (); // initialize the function every time you apply.} p-> child [* In-'a']-> Val + = val; // update the weight value on its subchain, the question is the cumulative probability P-> Child [* In-'a']-> I = I; // The overwriting process identifies the word to which each segment belongs. Do not worry about overwriting the previous records, it indicates that the prefix is the same, and the output result is the same as insert (p-> child [* In-'a'], in + 1, Val, I ); // recursive insert, the last two parameters remain unchanged}/* void Update (node * P) {for (INT I = 2; I <= 9; ++ I) // perform region solving on keys 2-9 {int max = 0, Rec =-1; // The maximum value is initialized to '0' when the node is applied ', the optimal solution is '-1' for (Int J = search [I] [0]; j <= search [I] [1]; ++ J) // search for the character area {If (p-> child [J]) corresponding to each key {// if the branch has if (max <p-> CH ILD [J]-> Val) // compare its value with the maximum value here to determine whether it may become its optimal solution {max = p-> child [J]-> val; rec = J;} Update (p-> child [J]); // deep Priority Search} p-> Best [I] = REC ;}} */node * Get (node * P, char * opr, int optimes) {int op = * (OPR)-'0 '; // convert OPR to an integer if (optimes) {for (INT I = search [op] [0]; I <= search [op] [1]; ++ I) {If (optimes) {If (p-> child [I]) {Get (p-> child [I], opr + 1, optimes-1 );}}} return cmpa;} else {return cm Pa = (p-> Val> cmpa-> Val? P: cmpa) ;}} void trans (node * P, char * op) {int Len = strlen (OP), optimes; node * fcmpa; For (INT I = 0; I <len-1; ++ I) {fcmpa = cmpa = Init (); optimes = I + 1; get (p, op, optimes ); if (cmpa-> I =-1) {puts ("manually") ;}else {for (Int J = 0; j <= I; ++ J) {printf ("% C", word [cmpa-> I] [J]) ;}puts ("") ;}free (fcmpa );}} void _ free (node * P) {// release the node of the tree. Note that the root node is also released, you need to re-apply for (INT I = 0; I <26; ++ I) {If (p-> child [I]) {_ free (p-> child [I]) ;}} free (p) ;}int main () {int T, W, M; scanf ("% d ", & T); For (int t = 1; t <= T; ++ t) {node * n = Init (); char op [105]; int val; // op [] is used to store the number sequence scanf ("% d", & W); For (INT I = 0; I <W; ++ I) {scanf ("% S % d", word [I], & Val); insert (n, word [I], Val, I );} // Update (n); printf ("Scenario # % d: \ n", T); scanf ("% d", & M); While (M --) {scanf ("% s", OP); If (W = 0) {puts ("manually") ;}else {TRANS (n, OP );} if (M> 0) {puts ("") ;}_ free (n); // release the tree printf ("\ n ");}} /* 13 abyb 3 abye 13 aaza 4122921 output: aababyaaza */