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

Type:

None

 

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 ( 1N105). 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 吐槽:有一年没写过字典树了,看以前的代码竟然感到很陌生,更可笑的是指针都不知道怎么用了。真是学得不如忘得快,但是好好看看,就很快懂了。 题目大意:给你n个不重复的字符串,每次敲一个字母,有相同前缀的字母都会自动出来,类似手机输入法。问你打出所有字符串平均需要敲多少下。如第一组样例。
hello 只需要敲3次,一次是h,一次是l,一次是o。 hell只需要敲2次,一次是h,一次是l。heaven需要敲2次,一次是h,一次是a。goodbye需要敲1次,即g。所以全部敲完是8次,平均值是2.00。

解题思路:用字典树模拟过程。我们在每个结点记录重复度rep,该结点下面有多少个分叉cross,是否是字符串结尾flag。对于分叉大于1的结点,我们需要加上该结点的重复度,表示需要在该结点下面的那些不同的字符处敲键盘。如果该结点同时是串尾的话,则需要减1,因为对于当前这个串,不需要在下面多敲一次就已经得到了。对于分叉不大于1的结点,我们判断它是否是串尾,如果是串尾,那么我们只需要加上重复度-1即可。最后加上串的个数n,表示对于每个字串,都需要敲1次最开始的那个字母。

#include<bits/stdc++.h>
using namespace std;
struct NODE {
int rep;
int cross;
bool flag;
NODE *next[26];
};
typedef NODE Trie;
NODE *newnode(){
Trie *tmp;
tmp= new Trie;
for(int i=0;i<26;i++)
tmp->next[i]=NULL;
tmp->flag=0;
tmp->cross=0;
tmp->rep=0;
return tmp;
}
void Insert ( Trie *rt, char *s ) {
int len = strlen ( s );
int idx;
for ( int i = 0; i < len; i++ ) {
idx = s[i] - 'a';
if(rt->next[idx] == NULL)
{
rt->next[idx] = newnode() ;
rt->cross++;
}
rt=rt->next[idx];
rt->rep++;
}
rt->flag=1;
}
double dfs(Trie *rt){
double ret=0;
for(int i=0;i<26;i++){
if(rt->next[i]!=NULL){
ret+=dfs(rt->next[i]);
}
}
if(rt->cross>1){
ret+=rt->rep;
if(rt->flag==1){
ret--;
}
}else if(rt->flag==1){
ret+=rt->rep-1;
}
delete rt;
return ret;
}
int main() { int n;
char str[100];
while ( scanf ( "%d", &n ) != EOF ) {
Trie *root;
root=newnode();
for ( int i = 0; i < n; i++ ) {
scanf ( "%s", str );
Insert ( root, str );
}
double ans=dfs(root);
printf("%.2lf\n",(n+ans)/n*1.0);
}
return 0;
}

  

BNU 27847——Cellphone Typing——————【字典树】的更多相关文章

  1. Cellphone Typing 字典树

    Cellphone Typing Time Limit: 5000ms Memory Limit: 131072KB   This problem will be judged on UVA. Ori ...

  2. POJ 1451 - T9 - [字典树]

    题目链接:http://bailian.openjudge.cn/practice/1451/ 总时间限制: 1000ms 内存限制: 65536kB 描述 Background A while ag ...

  3. HDU1298 字典树+dfs

    T9 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submissi ...

  4. HDU 1298 T9【字典树增加||查询】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=1298 T9 Time Limit: 2000/1000 MS (Java/Others)    Memo ...

  5. Tire树(字典树)

    from:https://www.cnblogs.com/justinh/p/7716421.html Trie,又经常叫前缀树,字典树等等.它有很多变种,如后缀树,Radix Tree/Trie,P ...

  6. 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)

    前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...

  7. [LeetCode] Implement Trie (Prefix Tree) 实现字典树(前缀树)

    Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...

  8. 字典树+博弈 CF 455B A Lot of Games(接龙游戏)

    题目链接 题意: A和B轮流在建造一个字,每次添加一个字符,要求是给定的n个串的某一个的前缀,不能添加字符的人输掉游戏,输掉的人先手下一轮的游戏.问A先手,经过k轮游戏,最后胜利的人是谁. 思路: 很 ...

  9. 萌新笔记——C++里创建 Trie字典树(中文词典)(一)(插入、遍历)

    萌新做词典第一篇,做得不好,还请指正,谢谢大佬! 写了一个词典,用到了Trie字典树. 写这个词典的目的,一个是为了压缩一些数据,另一个是为了尝试搜索提示,就像在谷歌搜索的时候,打出某个关键字,会提示 ...

随机推荐

  1. iOS开发之蓝牙使用-建立连接的

    1.大佬笔记 CSDN 2.代码 github

  2. Bicoloring UVA - 10004 二分图判断

    \(\color{#0066ff}{题目描述}\) 多组数据,n=0结束,每次一个n,m,之后是边,问你是不是二分图 \(\color{#0066ff}{输入样例}\) 3 3 0 1 1 2 2 0 ...

  3. ExtJS 4.2.1学习笔记(二)——主题theme

    1                 UI组件基础 学习ExtJs就是学习组件的使用.ExtJs4对框架进行了重构,其中最重要的就是形成了一个结构及层次分明的组件体系,由这些组件形成了Ext的控件. E ...

  4. kuangbin专题七 HDU1754 I Hate It (单点修改维护最大值)

    很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问.当然,老师有 ...

  5. springboot开发环境搭建

    姓名:陈中娇   班级:软件151 第一步:在Eclipse下面配置Maven环境: 一.使用spring boot新建maven工程不在需要建立maven web工程,只要一般的maven工程就好了 ...

  6. react todolist代码优化

    Todolist.js import React, { Component,Fragment } from 'react'; import TodoItem from './TodoItem'; im ...

  7. linux系统安全加固--账号相关

    linux系统安全加固 一.账号相关 1.禁用或删除无用账号 减少系统无用账号,降低安全风险. 当我们的系统安装完毕后,系统默认自带了一些虚拟账户,比如bin.adm.lp.games.postfix ...

  8. Ubuntu系统升级遇到问题记录

    The upgrade needs a total of 99.7 M free space on disk '/boot'. Please free at least an additional 5 ...

  9. System.Collections.Generic.List<T> 与 System.Collections.ArrayList

    [推荐] System.Collections.Generic.List<T> [原因] 泛型集合类List<T>在操作值类型的集合时可以不进行 装箱/拆箱 处理. 使得性能较 ...

  10. ZPL打印机命令解释

    个人备忘: 1.装驱动,装驱动要装对应的ZPL或者EPL版本,目前发现GK888T无需选择,直接装GK888T即可,其他机型未知. 2.标签设计,文本部分用SimSun-ExtB字体,变量内容部分用Z ...