您的位置:首页 > 其它

Cellphone Typing - UVaLive 6133 Trie树

2014-08-22 00:17 316 查看
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);
  }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: