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 }

 

posted @ 2015-06-10 11:22  NowAndForever  阅读(202)  评论(0编辑  收藏  举报