zoukankan      html  css  js  c++  java
  • UVA 11732——Trie

    解题思路:

      首先我们可以发现:

        1.若两个字符串A、B不相等,且它们的公共前缀为S,则它们的比较次数为:2 * len(S) + 1;

        2.若两个字符串相等,设为A,则它们的比较次数为 2 * ( len(A) + 1 )    //注意考虑结束符''

      那么我们可以建立前缀树,在向前缀树中插入字符串的过程中,如果遇到分叉结点则需要进行比较。

      特别注意:"aaaa","aa"以及"aaaa","aaaa"的情况

      具体做法:

        Trie维护每个结点的val和flag,其中val表示经过每个结点的字符串个数,flag表示是否是分叉结点。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cctype>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 const int maxnode = 4000*1000 + 10;
     9 const int _size = 63;
    10 long long ans;
    11 
    12 struct Trie {
    13     int ch[maxnode][_size];
    14     int val[maxnode];
    15     int flag[maxnode];
    16     int sz;
    17     Trie() {
    18         sz = 1;
    19         memset(ch[0], 0, sizeof (ch[0]));
    20     }
    21     int idx(int c) {
    22         if(c == '') return 62;
    23         else if(isdigit(c)) return c - '0';
    24         else if(c >= 'A' && c <= 'Z') return c - 'A' + 10;
    25         else return c - 'a' + 36;
    26     }
    27     
    28     void insert(char *s) {
    29         int u = 0, n = strlen(s);
    30         val[u]++;
    31         int i;
    32         for(i = 0; i <= n; i++) {
    33             int c = idx(s[i]);
    34             if(!ch[u][c]) {
    35                 memset(ch[sz], 0, sizeof (ch[sz]));
    36                 ch[u][c] = sz++;
    37                 val[ch[u][c]] = 1;
    38                 if(val[u] > 1){
    39                     flag[u] = 1;
    40                     ans += (2*i+1) * (val[u]-val[ch[u][c]]);
    41                 }
    42             }
    43             else {
    44                 val[ch[u][c]]++;
    45                 if(flag[u]) ans += (2*i+1) * (val[u]-val[ch[u][c]]);
    46             }
    47             u = ch[u][c];
    48             
    49         }
    50         if(val[u] > 1) {
    51             flag[u] = 1;
    52             ans += (2*i) * (val[u]-1);
    53         }
    54     }
    55     
    56     void clear() {
    57         sz = 1;
    58         memset(val, 0 , sizeof val);
    59         memset(ch[0], 0, sizeof (ch[0]));
    60         memset(flag, 0, sizeof flag);
    61     }
    62 };
    63 
    64 char s[1010];
    65 Trie T;
    66 
    67 int main(int argc, const char * argv[]) {
    68    
    69     int n;
    70     int kase = 1;
    71     while(scanf("%d", &n) == 1 && n) {
    72         T.clear();
    73         ans = 0;
    74         for(int i = 0; i < n; i++) {
    75             scanf("%s", s);
    76             T.insert(s);
    77         }
    78         
    79         printf("Case %d: %lld
    ", kase++, ans);
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    DateTime的精度小问题
    使用For XML PATH 会影响Cross Apply 返回
    一个update的小故事
    行大小计算测试
    Sql Server 2008R2 遇到了BCP导入各种中文乱码的问题
    php-fpm 启动不了 libiconv.so.2找不到
    Git使用教程
    支付宝接口使用文档说明 支付宝异步通知
    Linux(CentOs6.4)安装Git
    NGINX防御CC攻击教程
  • 原文地址:https://www.cnblogs.com/Kiraa/p/6046408.html
Copyright © 2011-2022 走看看