Cellphone Typing 字典树

Cellphone Typing

Time Limit: 5000ms
Memory Limit: 131072KB
 
This problem will be judged on UVA. Original ID:  12526
64-bit integer IO format:  %lld      Java class name:  Main
Font Size:  +  -
Type:   None   Graph Theory       2-SAT       Articulation/Bridge/Biconnected Component       Cycles/Topological Sorting/Strongly Connected Component       Shortest Path           Bellman Ford           Dijkstra/Floyd Warshall       Euler Trail/Circuit       Heavy-Light Decomposition       Minimum Spanning Tree       Stable Marriage Problem       Trees       Directed Minimum Spanning Tree       Flow/Matching           Graph Matching               Bipartite Matching               Hopcroft–Karp Bipartite Matching               Weighted Bipartite Matching/Hungarian Algorithm           Flow               Max Flow/Min Cut               Min Cost Max Flow   DFS-like       Backtracking with Pruning/Branch and Bound       Basic Recursion       IDA* Search       Parsing/Grammar       Breadth First Search/Depth First Search       Advanced Search Techniques           Binary Search/Bisection           Ternary Search   Geometry       Basic Geometry       Computational Geometry       Convex Hull       Pick's Theorem   Game Theory       Green Hackenbush/Colon Principle/Fusion Principle       Nim       Sprague-Grundy Number   Matrix       Gaussian Elimination       Matrix Exponentiation   Data Structures       Basic Data Structures       Binary Indexed Tree       Binary Search Tree       Hashing       Orthogonal Range Search       Range Minimum Query/Lowest Common Ancestor       Segment Tree/Interval Tree       Trie Tree       Sorting       Disjoint Set   String       Aho Corasick       Knuth-Morris-Pratt       Suffix Array/Suffix Tree   Math       Basic Math       Big Integer Arithmetic       Number Theory           Chinese Remainder Theorem           Extended Euclid           Inclusion/Exclusion           Modular Arithmetic       Combinatorics           Group Theory/Burnside's lemma           Counting       Probability/Expected Value   Others       Tricky       Hardest       Unusual       Brute Force       Implementation       Constructive Algorithms       Two Pointer       Bitmask       Beginner       Discrete Logarithm/Shank's Baby-step Giant-step Algorithm       Greedy       Divide and Conquer   Dynamic Programming                      Tag it!

[PDF Link]

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 first letter of a word, so the first 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 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.

 

Input 

Each test case is described using several lines. The first line contains an integer N representing the number of words in the dictionary ( 1$ \le$N$ \le$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 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 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


题意:
先给你一些字符串,也就是所谓的字典;
然后先求查询每个单词最少要输入几个单词;

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);
    }
}

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/sweat123/p/4714975.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值