这道题也是卡了挺久的。

给出一个字符串比较的算法,有n个字符串两两比较一次,问一共会有多少次比较。

因为节点会很多,所以Tire树采用了左儿子右兄弟的表示法来节省空间。

假设两个不相等的字符串的最长公共前缀的长度为i,那么比较次数应该是2i+1。

如果两个字符串相等,比较次数则是2i+2.

可以像大白书上一样先构建好Tire树,然后DFS统计答案。

 1 #include <cstdio>
 2 #include <cstring>
 3 
 4 const int maxnode = 4000 * 1000 + 10;
 5 
 6 struct Tire
 7 {
 8     int sz;
 9     int son[maxnode], bro[maxnode], tot[maxnode];
10     char ch[maxnode];
11     long long ans;
12     void clear() { sz = 1; son[0] = bro[0] = tot[0] = 0; }
13 
14     void insert(char* s)
15     {
16         int u = 0, v, n = strlen(s);
17         tot[0]++;
18         for(int i = 0; i <= n; i++)
19         {
20             bool found = false;
21             for(v = son[u]; v; v = bro[v])
22                 if(ch[v] == s[i]) { found = true; break; }
23             if(!found)
24             {
25                 v = sz++;
26                 son[v] = 0;
27                 bro[v] = son[u];
28                 son[u] = v;
29                 tot[v] = 0;
30                 ch[v] = s[i];
31             }
32             u = v;
33             tot[u]++;
34         }
35     }
36 
37     void dfs(int d, int u)
38     {
39         if(son[u] == 0) { ans += tot[u] * (tot[u]-1) * d; return; }//叶节点
40         long long sum = 0;
41         for(int v = son[u]; v; v = bro[v])
42             sum += tot[v] * (tot[u] - tot[v]);
43         ans += sum / 2 * (d * 2 + 1);
44         for(int v = son[u]; v; v = bro[v]) dfs(d+1, v);
45     }
46 
47     long long count()
48     {
49         ans = 0;
50         dfs(0, 0);
51         return ans;
52     }
53 }tire;
54 
55 const int maxl = 1000 + 10;
56 char s[maxl];
57 
58 int main()
59 {
60     //freopen("in.txt", "r", stdin);
61 
62     int n, kase = 0;
63     while(scanf("%d", &n) == 1 && n)
64     {
65         tire.clear();
66         for(int i = 0; i < n; i++) { scanf("%s", s); tire.insert(s); }
67         printf("Case %d: %lld\n", ++kase, tire.count());
68     }
69 
70     return 0;
71 }
代码君

相关文章:

  • 2021-04-05
  • 2021-09-20
  • 2021-12-19
  • 2022-01-02
  • 2021-08-10
  • 2022-12-23
  • 2022-12-23
  • 2021-07-29
猜你喜欢
  • 2021-09-05
  • 2022-02-10
  • 2021-06-28
  • 2021-10-16
  • 2021-10-10
  • 2021-08-16
  • 2022-02-16
相关资源
相似解决方案