CSU - 1115 最短的名字(字典树模板题)
Description
在一个奇怪的村子中,很多人的名字都很长,比如aaaaa, bbb and abababab。
名字这么长,叫全名显然起来很不方便。所以村民之间一般只叫名字的前缀。比如叫'aaaaa'的时候可以只叫'aaa',因为没有第二个人名字的前三个字母是'aaa'。不过你不能叫'a',因为有两个人的名字都以'a'开头。村里的人都很聪明,他们总是用最短的称呼叫人。输入保证村里不会有一个人的名字是另外一个人名字的前缀(作为推论,任意两个人的名字都不会相同)。
如果村里的某个人要叫所有人的名字(包括他自己),他一共会说多少个字母?
Input
输入第一行为数据组数T (T<=10)。每组数据第一行为一个整数n(1<=n<=1000),即村里的人数。以下n行每行为一个人的名字(仅有小写字母组成)。输入保证一个村里所有人名字的长度之和不超过1,000,000。
Output
对于每组数据,输出所有人名字的字母总数。
Sample Input
1
3
aaaaa
bbb
abababab
Sample Output
5
http://acm.csu.edu.cn/OnlineJudge/problem.php?cid=2081&pid=15
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <vector> 5 #include <cstring> 6 #include <string> 7 #include <algorithm> 8 #include <string> 9 #include <set> 10 #include <functional> 11 #include <numeric> 12 #include <sstream> 13 #include <stack> 14 #include <map> 15 #include <queue> 16 #pragma comment(linker, "/STACK:102400000,102400000") 17 #define CL(arr, val) memset(arr, val, sizeof(arr)) 18 19 #define ll long long 20 #define inf 0x7f7f7f7f 21 #define lc l,m,rt<<1 22 #define rc m + 1,r,rt<<1|1 23 #define pi acos(-1.0) 24 25 #define L(x) (x) << 1 26 #define R(x) (x) << 1 | 1 27 #define MID(l, r) (l + r) >> 1 28 #define Min(x, y) (x) < (y) ? (x) : (y) 29 #define Max(x, y) (x) < (y) ? (y) : (x) 30 #define E(x) (1 << (x)) 31 #define iabs(x) (x) < 0 ? -(x) : (x) 32 #define OUT(x) printf("%I64d\n", x) 33 #define lowbit(x) (x)&(-x) 34 #define Read() freopen("a.txt", "r", stdin) 35 #define Write() freopen("b.txt", "w", stdout); 36 #define maxn 1010 37 #define maxv 1010 38 #define mod 1000000000 39 using namespace std; 40 41 typedef struct node 42 { 43 int count; 44 struct node *next[26]; 45 }*tree; 46 47 void insert(tree h,char *s) 48 { //每一个节点保存的都是每一个字母出现的次数。 49 tree p=h; 50 int len=strlen(s); 51 for(int i=0;i<len;i++) 52 { 53 int index=s[i]-'a'; 54 if(p->next[index]!=NULL) 55 { 56 p=p->next[index]; 57 p->count++; 58 } 59 else 60 { 61 tree tem=(tree)calloc(1,sizeof(node)); 62 tem->count=1; 63 p->next[index]=tem; 64 p=tem; 65 } 66 } 67 } 68 69 int find(tree h) 70 { //查找不为空的结点,加上相应的次数,如果count值大于1,则说明有分支,需继续查找下去 71 tree p=h; 72 int sum=0,i; 73 for(int i=0;i<26;i++) 74 { 75 if(h->next[i]!=NULL) 76 { 77 p=h->next[i]; 78 sum+=p->count; 79 if(p->count>1) sum+=find(p); 80 } 81 } 82 return sum; 83 } 84 85 char s[1000]; 86 87 int main() 88 { 89 //freopen("a.txt","r",stdin); 90 int t,n; 91 scanf("%d",&t); 92 while(t--) 93 { 94 scanf("%d",&n); 95 tree head=(tree)calloc(1,sizeof(node)); 96 while(n--) 97 { 98 scanf("%s",s); 99 insert(head,s); 100 } 101 printf("%d\n",find(head)); 102 free(head); 103 } 104 return 0; 105 }