• UVa 11732 (Tire树) "strcmp()" Anyone?


    这道题也是卡了挺久的。

    给出一个字符串比较的算法,有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
    ", ++kase, tire.count());
    68     }
    69 
    70     return 0;
    71 }
    代码君

    也可以边插入字符串边统计,代码更短,而且速度也更快。这种做法是从某位菊苣的博客中看到的。

     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 const int maxnode = 1000 * 4000 + 10;
     5 
     6 long long ans;
     7 
     8 struct Tire
     9 {
    10     int son[maxnode], bro[maxnode], tot[maxnode];
    11     char ch[maxnode];
    12     int sz;
    13     void clear() { sz = 1; son[0] = bro[0] = tot[0] = 0; }
    14 
    15     void insert(char* s)
    16     {
    17         int u = 0, v, n = strlen(s);
    18         tot[0]++;
    19         for(int i = 0; i <= n; i++)
    20         {
    21             bool found = false;
    22             for(v = son[u]; v; v = bro[v])
    23                 if(ch[v] == s[i]) { found = true; break; }
    24             if(!found)
    25             {
    26                 v = sz++;
    27                 son[v] = 0;
    28                 bro[v] = son[u];
    29                 son[u] = v;
    30                 tot[v] = 0;
    31                 ch[v] = s[i];
    32             }
    33             ans += (tot[u] - 1 - tot[v]) * (2 * i + 1);
    34             if(i == n) ans += tot[v] * (2 * i + 2);
    35             u = v;
    36             tot[u]++;
    37         }
    38     }
    39 }tire;
    40 
    41 const int maxl = 1000 + 10;
    42 char s[maxl];
    43 
    44 int main()
    45 {
    46     //freopen("in.txt", "r", stdin);
    47 
    48     int n, kase = 0;
    49     while(scanf("%d", &n) == 1 && n)
    50     {
    51         tire.clear();
    52         ans = 0;
    53         for(int i = 0; i < n; i++) { scanf("%s", s); tire.insert(s); }
    54         printf("Case %d: %lld
    ", ++kase, ans);
    55     }
    56 
    57     return 0;
    58 }
    代码君
  • 相关阅读:
    while语句
    闭包
    文件操作
    Python基础九:高级特性
    Python基础八:函数
    Python基础六:字典和集合
    Python基础七:条件判断和循环结构
    Python基础五:列表和元组
    Python基础四:字符串及编码
    Python基础三:数据类型和变量
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4390366.html
Copyright © 2020-2023  润新知