[UVA][Trie] 12526 - Cellphone Typing
However, this is not fast enough. The team is going to put together a dictionary of the commonwords that a user may type. The goal is to reduce the average number of keystrokes needed to typewords that are in the dictionary. During the typing of a word, whenever the following letter is uniquelydetermined, the cellphone system will input it automatically, without the need for a keystroke. To bemore precise, the behavior of the cellphone system will be determined by the following rules:
- The system never guesses the first letter of a word, so the first letter always has to be inputmanually by pressing the corresponding key.
- If a non-empty succession of letters c1c2...cn has been input, and there is a letter c such thatevery word in the dictionary which starts with c1c2...cn also starts with c1c2...cnc, then thesystem inputs c automatically, without the need of a keystroke. Otherwise, the system waits forthe user.
For instance, if the dictionary is composed of the words `hello', `hell', `heaven' and `goodbye',and the user presses `h', the system will input `e' automatically, because every word which startswith `h' also starts with `he'. However, since there are 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 will input a second `l' automatically. When it has `hell' as input, the systemcannot guess, because it is possible that the word is over, or it is also possible that the user may wantto press `o' to get `hello'. In this fashion, to type the word `hello' the user needs three keystrokes,`hell' requires two, and `heaven' also requires two, because when the current input is `hea' thesystem 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' thesystem will automatically fill in the entire word. In this example, the average number of keystrokesneeded to type a word in the dictionary is then (3 + 2 + 2 + 1)/4 = 2.00.
Your task is, given a dictionary, to calculate the average number of keystrokes needed to type aword in the dictionary with the new cellphone system.
Input
Each test case is described using several lines. The first line contains an integer N representing thenumber of words in the dictionary (1N105). Each of the next N lines contains a non-emptystring of at most 80 lowercase letters from the English alphabet, representing a word in the dictionary.Within each test case all words are different, and the sum of the lengths of all words is at most 106.Output
For each test case output a line with a rational number representing the average number of keystrokesneeded to type a word in the dictionary. The result must be output as a rational number with exactlytwo digits after the decimal point, rounded if necessary.Sample Input
4
hello
hell
heaven
goodbye
3
hi
he
h
7
structure
structures
ride
riders
stress
solstice
ridiculous
Sample Output
2.00
1.67
2.71
建出一個 Trie,對每個到葉節點的路徑紀錄其分支度大於1的個數,加總即可。
#include <stdio.h>
#include <string.h>
struct Trie {
bool n;
int link[26], cnt, b;
} Node[1048576];
int TrieSize;
int insertTrie(const char *str) {
static int i, idx;
idx = 0;
for(i = 0; str[i]; i++) {
if(!Node[idx].link[str[i]-'a']) {
TrieSize++;
memset(&Node[TrieSize], 0, sizeof(Node[0]));
Node[idx].link[str[i]-'a'] = TrieSize;
Node[idx].b++;
}
Node[idx].cnt++;
idx = Node[idx].link[str[i]-'a'];
}
Node[idx].n = true, Node[idx].b++;
return 0;
}
int ans;
void dfs(int nd, int dep, int cc) {
if(Node[nd].n == true) {
ans += cc;
}
int i, plus;
plus = Node[nd].b != 1;
for(i = 0; i < 26; i++) {
if(Node[nd].link[i]) {
dfs(Node[nd].link[i], dep+1, cc+plus);
}
}
}
char str[100];
int main() {
int n, on;
while(scanf("%d ", &n) == 1) {
on = n;
TrieSize = 0;
memset(&Node[0], 0, sizeof(Node[0]));
while(n--) {
gets(str);
insertTrie(str);
}
ans = 0;
for(int i = 0; i < 26; i++)
if(Node[0].link[i])
dfs(Node[0].link[i], 1, 1);
printf("%.2lf\n", (double)ans/on);
}
return 0;
}