题目描述:
Autocomplete25 points
Since you crave state-of-the-art technology, you‘ve just purchased a phone with a great new feature: autocomplete! Your phone‘s version of autocomplete has some pros and cons. On the one hand, it‘s very cautious.
It only autocompletes a word when it knows exactly what you‘re trying to write. On the other hand, you have to teach it every word you want to use.
You have N distinct words that you‘d like to send in a text message in order. Before sending each word, you add it to your phone‘s dictionary. Then, you write the smallest non-empty prefix of the
word necessary for your phone to autocomplete the word. This prefix must either be the whole word, or a prefix which is not a prefix of any other word yet in the dictionary.
What‘s the minimum number of letters you must type to send all N words?
Input
Input begins with an integer T, the number of test cases. For each test case, there is first a line containing the integer N. Then,N lines follow, each containing
a word to send in the order you wish to send them.
Output
For the ith test case, print a line containing "Case #i: " followed by the minimum number of characters you need to type in your text message.
Constraints
1 ≤ T ≤ 100
1 ≤ N ≤ 100,000
The N words will have a total length of no more than 1,000,000 characters.
The words are made up of only lower-case alphabetic characters.
The words are pairwise distinct.
NOTE: The input file is about 10-20MB.
Explanation of Sample
In the first test case, you will write "h", "he", "l", "hil", "hill", for a total of 1 + 2 + 1 + 3 + 4 = 11 characters.
Example input ·
Example output ·
5 5 hi hello lol hills hill 5 a aa aaa aaaa aaaaa 5 aaaaa aaaa aaa aa a 6 to be or not two bee 3 having fun yet
Case #1: 11 Case #2: 15 Case #3: 11 Case #4: 9 Case #5: 3
解题思路:
使用字典树可以求出该字符串是否和其他字符串有公共前缀。具体看代码
题目代码:
#include <set> #include <map> #include <queue> #include <math.h> #include <vector> #include <string> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <cctype> #include <algorithm> #define eps 1e-10 #define pi acos(-1.0) #define inf 107374182 #define inf64 1152921504606846976 #define lc l,m,tr<<1 #define rc m + 1,r,tr<<1|1 #define zero(a) fabs(a)<eps #define iabs(x) ((x) > 0 ? (x) : -(x)) #define clear1(A, X, SIZE) memset(A, X, sizeof(A[0]) * (min(SIZE,sizeof(A)))) #define clearall(A, X) memset(A, X, sizeof(A)) #define memcopy1(A , X, SIZE) memcpy(A , X ,sizeof(X[0])*(SIZE)) #define memcopyall(A, X) memcpy(A , X ,sizeof(X)) #define max( x, y ) ( ((x) > (y)) ? (x) : (y) ) #define min( x, y ) ( ((x) < (y)) ? (x) : (y) ) using namespace std; struct node { int p[27]; int cnt; bool alive; } treenode[1000005]; int ans,nodecnt; char s[1000005]; void insertto() { int len=strlen(s),p=0; ans++; if(treenode[p].p[s[0]-'a']==0) { clearall(treenode[nodecnt].p,0); treenode[nodecnt].cnt=0; treenode[nodecnt].alive=false; treenode[p].p[s[0]-'a']=nodecnt++; } p=treenode[p].p[s[0]-'a']; treenode[p].cnt++; for(int i=1; i<len; i++) { if(treenode[p].p[s[i]-'a']==0) { clearall(treenode[nodecnt].p,0); treenode[nodecnt].cnt=0; treenode[nodecnt].alive=false; treenode[p].p[s[i]-'a']=nodecnt++; } if(treenode[p].cnt==1&&treenode[treenode[p].p[s[i]-'a']].cnt==0) { } else ans++; treenode[treenode[p].p[s[i]-'a']].cnt++; p= treenode[p].p[s[i]-'a']; } } int main() { //freopen("data.in","r",stdin); //freopen("data.txt","w",stdout); int t,case1=1; while(scanf("%d",&t)!=EOF) { while(t--) { clearall(treenode[0].p,0); treenode[0].cnt=0; treenode[0].alive=false; nodecnt=1; ans=0; int n; scanf("%d",&n); for(int i=0; i<n; i++) { scanf("%s",s); insertto(); //printf("%d\n",ans); } printf("Case #%d: %d\n",case1++,ans); } } return 0; }
题目最终测试数据:
链接: http://pan.baidu.com/s/1o6oiwY2
密码: 1dgp