【uva11732-"strcmp()" Anyone?】Trie

http://acm.hust.edu.cn/vjudge/problem/28438

题意:给定n个字符串,问用strcmp函数比较这些字符串共用多少次比较。

题解:

插入一个‘#’作为字符串的结束符,避免特殊判断太乱。
插入的时候,如果走过以前插入的字符,那就把比较的次数加上。
要用long long。

 1 //uva11732
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<iostream>
 6 using namespace std;
 7 
 8 typedef long long LL;
 9 const LL N=4100,L=1100;
10 char s[L];
11 LL n,num,ans;
12 struct node{
13     LL d,son,right,sum,len;
14 }a[N*L];
15 
16 void clear(LL x)
17 {
18     a[x].d=a[x].sum=a[x].len=0;
19     a[x].son=a[x].right=-1;
20 }
21 
22 void insert(char *s,LL l)
23 {
24     LL x=0;
25     for(LL i=0;i<l;i++)
26     {
27         bool found=0;
28         LL now=30,next;
29         if(s[i]!='#') now=s[i]-'a'+1;
30         for(LL y=a[x].son;y!=-1;y=a[y].right)
31         {
32             if(a[y].d==now) 
33             {
34                 found=1;
35                 ans+=2*a[y].sum;
36                 next=y;
37             }
38             else ans+=a[y].sum;
39         }
40         if(!found)
41         {
42             num++;
43             clear(num);
44             a[num].d=now;
45             a[num].len=i+1;
46             if(a[x].son==-1) a[x].son=num;
47             else 
48             {
49                 LL t=a[x].son;
50                 while(a[t].right!=-1) 
51                     t=a[t].right;
52                 a[t].right=num;
53             }
54             
55             next=num;
56         }
57         x=next;
58         a[x].sum++;
59     }
60 }
61 
62 int main()
63 {
64     freopen("a.in","r",stdin);
65     freopen("a.out","w",stdout);
66     LL T=0;
67     while(1)
68     {
69         scanf("%lld",&n);getchar();
70         if(!n) return 0;
71         num=0;ans=0;clear(0);
72         for(LL i=1;i<=n;i++)
73         {
74             scanf("%s",s);
75             LL l=strlen(s);
76             s[l]='#';l++;
77             insert(s,l);
78         }
79         printf("Case %lld: %lld
",++T,ans);
80     }
81     
82     return 0;
83 }
84 /*
85 A!=B 1
86 A==B 2
87 */