标签:
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:
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 fill 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.
4 hello hell heaven goodbye 3 hi he h 7 structure structures ride riders stress solstice ridiculous
2.00 1.67 2.71
题意:
先给你一些字符串,也就是所谓的字典;
然后先求查询每个单词最少要输入几个单词;
如
4
hello
hell
heaven
goodbye
如果输入g,那只有唯一一个g开头的,所以只要1个就可以。
输入h,由于h开头的都有e,所以e不需要输入,再输入l,相同理由此l不需要输入,再输入o,才能找到hello
解法:
对于每一个单词,至少要找到他,那就要找到他与其他单词不同的地方。hello hell 不同于最后的o。
可以再trie结构体里面多加几个条件,way表示接下去的种数,sum表示该单词使用次数,flag表示是否有单词;
如果该点的way>1,表示有多种路可以走。那此时ans+=p->sum,因为每个单词都要输入下面那个单词,如果现在这个位置有完整的一个字符串了,那ans--,因为他不用再输入了;如果此时way==1,并且这里有完整的单词时,那就要ans+=p->sum-1。(要注意这里的sum表示的意思)
#include<stdio.h> #include<string.h> #include<stdlib.h> #define maxn 26 struct trie { trie *next[maxn]; int sum; int way;//记录分支的数量 int flag;//标记 }; char str[1000010]; trie *root; void init() { root=(trie*)malloc(sizeof(trie)); for(int i=0;i<maxn;i++) root->next[i]=NULL; root->sum=0; root->flag=0; root->way=0; } void insert(char s[]) { trie *p=root,*q; int i,j,len=strlen(s); for(i=0;i<len;i++) { int id=s[i]-‘a‘; if(p->next[id]==NULL) { p->way++; q=(trie*)malloc(sizeof(trie)); for(j=0;j<maxn;j++) q->next[j]=NULL; q->sum=0; q->flag=0; q->way=0; p->next[id]=q; } p=p->next[id]; p->sum++; if(i==len-1) p->flag=1; } } int getans(trie *p) { int i,j,ans=0; for(i=0;i<26;i++) { if(p->next[i]!=NULL) { ans+=getans(p->next[i]); } } if(p->way>1) { if(p->flag>0) { ans--; } ans+=p->sum; } else if(p->flag>0) { ans+=p->sum-1;//如果为串尾; } free(p); return ans; } int main() { int i,j,t,m; while(scanf("%d",&t)!=EOF) { init(); m=t; while(t--) { scanf("%s",str); insert(str); } int ans=getans(root)+m; printf("%.2lf\n",ans*1.0/m); } }
标签:
原文地址:http://www.cnblogs.com/sweat123/p/4714975.html