BNU 27847--cellphone Typing —————— "Dictionary tree"

Source: Internet
Author: User
Tags repetition

Cellphone typingtime limit:5000msmemory limit:131072kbthis problem would be judged onUVA. Original id:12526
64-bit integer IO format: %lld Java class name: Main Prev Submit Status Statistics discuss Next

[PDF Link]

A team is developing a new technology to save time when typing text messages in mobile devices. They is working on a new model the have a complete keyboard, so users can type any single letter by pressing the CORRESPO Nding key. In this, a user needs P keystrokes to type a word of length P.

However, this is not fast enough. The team is going to put together a dictionary of the common words this a user may type. The goal is to reduce the average number of keystrokes needed to type words that was in the dictionary. During The typing of a word, whenever the following letter is uniquely determined, the cellphone system would input it auto Matically, without the need for a keystroke. To is more precise, the behavior of the cellphone system would be determined by the following rules:

    1. The system never guesses the first letter of a word, so the first letter always have to is input manually by pressing the C Orresponding key.
    2. If a non-empty succession of letters C1C2 ... CN has been input, and there are a letter C Such this every word in the dictionary which starts with C1C2 ... cN also starts with c1C2 ... CNC, then the system inputs C automatically, without the need of a keystroke. Otherwise, the system waits for the user.

For instance, if the dictionary is composed of the words 'Hello', 'Hell', 'Heaven' and 'Goodbye', and the user presses 'h', the system would input 'e' Automatically, because every word which starts with 'h' also starts with 'He‘. However, since there is words that start with 'Hel' And with 'Hea', the system now needs-to-wait for the user. If the user then presses 'L', obtaining the partial word 'Hel', the system would input a second 'L' Automatically. When it had 'Hell' As input, the system cannot guess, because it is possible, the word was over, or it was also possible that the user Ma Y want to press 'o' To get 'Hello‘. In this fashion, to type the word 'Hello' The user needs three keystrokes, 'Hell' Requires, and 'Heaven' also requires, because when the current input is 'Hea' The system can automatically input the remainder of the word by repeatedly applying the second rule. Similarly, the word 'Goodbye' Needs just one keystroke, because after pressing the initial 'g' The system would automatically fill in the entire word. In this example, the average number of keystrokes needed to type a word in the dictionary are then (3 + 2 + 2 + 1)/4 = 2.00 .

Your task is, given a dictionary, to calculate the average number of keystrokes needed to type a word in the dictionary WI Th the new cellphone system.

InputEach test case is described using several lines. The first line contains a integer N representing the number of words in the dictionary ( 1 N105) . Each of the next N lines contains a non-empty string of in most lowercase letters from the Chinese Alphabe T, representing a word in the dictionary. Within each test case all words was different, and the sum of the lengths of all words was at most 106.

OutputFor each test case output a line with a rational number representing the average number of keystrokes needed to type a Word in the dictionary. The result must is output as a rational number with exactly-digits after the decimal point, rounded if necessary.

Sample Input

4hellohellheavengoodbye3hiheh7structurestructuresrideridersstresssolsticeridiculous

Sample Output

2.001.672.71

Spit Groove: A year has not written a dictionary tree, look at the previous code unexpectedly feel very strange, more ridiculous is the pointer do not know how to use. It's better to forget quickly than to learn, but take a good look, and soon understand.

The main idea: to give you n a non-repeating string, each time you hit a letter, the same prefix letters will automatically come out, similar to the phone input method. Ask how many times you have to hit all the strings on average. such as the first set of examples.
Hello only needs to knock 3 times, once is H, once is L, once is O. Hell only need to knock 2 times, once is H, once is L. Heaven need to knock 2 times, one is H, one is a. Goodbye need to knock 1 times, that is G. So the total knock is 8 times, the average is 2.00.

The idea of solving problems: Using the dictionary tree to simulate the process. We record the repetition rep at each node, how many forks cross below the node, and whether it is the end of the string flag. For a node with a fork greater than 1, we need to add the repetition of that node, which means that the prompt of the different characters below that node is required to hit the keyboard. If the node is also at the end of the string, you need to subtract 1, because for the current string, you do not need to knock more than once to get it. For a fork of not more than 1 of the node, we determine whether it is a string tail, if it is the end, then we only need to add a repetition of 1. Finally, the number of strings, n, means that for each string, you need to knock 1 times the beginning of the letter.


#include <bits/stdc++.h>using namespace std;struct NODE {int rep;    int cross;    BOOL Flag; NODE *next[26];}; typedef NODE Trie;    NODE *newnode () {Trie *tmp;    tmp= new Trie;    for (int i=0;i<26;i++) tmp->next[i]=null;    tmp->flag=0;    tmp->cross=0;    tmp->rep=0; return TMP;}    void Insert (Trie *rt, char *s) {int len = strlen (s);    int idx;        for (int i = 0; i < len; i++) {idx = s[i]-' a ';            if (rt->next[idx] = = NULL) {Rt->next[idx] = NewNode ();        rt->cross++;        } rt=rt->next[idx];    rt->rep++; } rt->flag=1;}    Double Dfs (Trie *rt) {double ret=0;        for (int i=0;i<26;i++) {if (rt->next[i]!=null) {Ret+=dfs (rt->next[i]);        }} if (rt->cross>1) {ret+=rt->rep;        if (rt->flag==1) {ret--;    }}else if (rt->flag==1) {ret+=rt->rep-1;    } Delete rt; return ret;} INT main () {int n;    Char str[100];        while (scanf ("%d", &n)! = EOF) {Trie *root;        Root=newnode ();            for (int i = 0; i < n; i++) {scanf ("%s", str);        Insert (root, str);        } double Ans=dfs (root);    printf ("%.2lf\n", (N+ans)/n*1.0); } return 0;}

  

BNU 27847--cellphone Typing —————— "Dictionary tree"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.