A research team is developing a new technology to save time when typing text messages in mobile
devices. They are working on a new model that has a complete keyboard, so users can type any single
letter by pressing the corresponding key. In this way, 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 that a user may type. The goal is to reduce the average number of keystrokes needed to type
words that are in the dictionary. During the typing of a word, whenever the following letter is uniquely
determined, the cellphone system will input it automatically, without the need for a keystroke. To be
more precise, the behavior of the cellphone system will be determined by the following rules:
1. The system never guesses the rst letter of a word, so the rst letter always has to be input
manually by pressing the corresponding key.
2. If a non-empty succession of letters c1c2 : : : cn has been input, and there is a letter c such that
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 will input `e' automatically, because every word which starts with
`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 system cannot guess, because
it is possible that the word is over, or it is also possible that the user may want to 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' 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 will automatically ll in the
entire word. In this example, the average number of keystrokes needed 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 a
word in the dictionary with the new cellphone system.
Input
Each test case is described using several lines. The rst line contains an integer N representing the
number of words in the dictionary (1 N 105
). Each of the next N lines contains a non-empty
string of at most 80 lowercase letters from the English alphabet, representing a word in the dictionary.
Within each test case all words are di erent, 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 keystrokes
needed to type a word in the dictionary. The result must be output as a rational number with exactly
two 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树,没什么好说的。
AC代码如下:
#include<cstdio>
#include<cstring>
using namespace std;
char s[100010][90];
int num[100010],length[100010],sum;
struct Trie
{ int index,num;
Trie *next[26];
Trie()
{ index=-1,num=-1;
memset(next,0,sizeof(next));
}
};
void Trie_Insert(Trie *tr,char *s)
{ if(*s!='\0')
{ if(tr->next[*s-'a']==0)
tr->next[*s-'a']=new Trie;
Trie_Insert(tr->next[*s-'a'],s+1);
}
else
tr->index=0;
}
void Trie_Search(Trie *tr,int pos,int len)
{ if(tr->num==-1)
{ int i,k=0;
for(i=0;i<=25;i++)
if(tr->next[i]!=0)
k++;
tr->num=k;
}
if( !((tr->index==-1 && tr->num==1) || (tr->index==0 && tr->num==0)) )
num[pos]++;
if(len>=length[pos])
{ if(tr->num>0)
num[pos]--;
return;
}
Trie_Search(tr->next[s[pos][len]-'a'],pos,len+1);
}
int main()
{ int t,n,i,j,k;
while(~scanf("%d",&n))
{ Trie *root=new Trie;
for(i=1;i<=n;i++)
{ scanf("%s",s[i]);
Trie_Insert(root,s[i]);
length[i]=strlen(s[i]);
}
memset(num,0,sizeof(num));
for(i=1;i<=n;i++)
Trie_Search(root->next[s[i][0]-'a'],i,1);
sum=0;
for(i=1;i<=n;i++)
sum+=num[i];
sum+=n;
printf("%.2f\n",1.0*sum/n);
}
}