• Uva 11732 strcmp()函数


    题目链接:https://vjudge.net/contest/158125#problem/A

    题意:

    系统中,strcmp函数是这样执行的,给定 n 个字符串,求两两比较时,strcmp函数要比较多少次?

    如:

    t  h  a  n         t  h  e  r  e  

    t  h  a  t          t  h  e  

    2  2  2  1            2  2  2  1

    直接两两比较是超时的。

    可以这样建立一个字典树:

    可以发现一直要比较到交叉处,和这个交叉点的深度有关(2*depth+1)。

    1、这个字典序每一个交叉点都是要计算的,所以采用邻接表的形式存图;

    2、每个结点都要计算他的叶子结点的个数,当分叉的时候,那么说明这里有两个(多个)不同的单词,从中要选择两个单词,计算有多少种搭配,比较次数就是这些搭配*(2*depth+1);

    3、递归找下一个结点。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int maxnode = 4000 * 1000 + 10;
     6 const int sigma_size = 26;
     7 
     8 struct Trie
     9 {
    10     int head[maxnode];
    11     int next[maxnode];
    12     char ch[maxnode];
    13     int tot[maxnode];
    14     int sz;
    15     long long ans;
    16     void clear()
    17     {
    18         sz = 1;
    19         tot[0] = head[0] = next[0] = 0;
    20     }
    21 
    22     void insert(const char *s)
    23     {
    24         int u = 0, v, n = strlen(s);
    25         tot[0]++;
    26         for(int i = 0; i <= n; i++)
    27         {
    28             // 找字符a[i]
    29             bool found = false;
    30             for(v = head[u]; v != 0; v = next[v])
    31                 if(ch[v] == s[i])   // 找到了
    32                 {
    33                     found = true;
    34                     break;
    35                 }
    36             if(!found)
    37             {
    38                 v = sz++; // 新建结点
    39                 tot[v] = 0;
    40                 ch[v] = s[i];
    41                 next[v] = head[u];
    42                 head[u] = v; // 插入到链表的首部
    43                 head[v] = 0;
    44             }
    45             u = v;
    46             tot[u]++;
    47         }
    48     }
    49 
    50 
    51     void dfs(int depth,int u)
    52     {
    53         if(head[u]==0) //叶子节点
    54             ans+=tot[u]*(tot[u]-1)*depth;
    55         else
    56         {
    57             int sum =0;
    58             for(int v=head[u]; v!=0; v=next[v])
    59             {
    60                 sum+=tot[v]*(tot[u]-tot[v]);
    61             }
    62             ans+=sum/2*(2*depth+1);
    63             for(int v=head[u]; v!=0; v=next[v])
    64                 dfs(depth+1,v);
    65         }
    66     }
    67 
    68     long long count()
    69     {
    70         ans = 0;
    71         dfs(0,0);
    72         return ans;
    73     }
    74 
    75 } trie;
    76 
    77 char word[1010];
    78 
    79 int main()
    80 {
    81     int n;
    82     int kase = 1;
    83     while(scanf("%d",&n),n)
    84     {
    85         trie.clear();
    86         for(int i=0; i<n; i++)
    87         {
    88             scanf("%s",word);
    89             trie.insert(word);
    90         }
    91         printf("Case %d: %lld
    ",kase++,trie.count());
    92     }
    93 
    94     return 0;
    95 }
    View Code
  • 相关阅读:
    在Eclipse中写第一个hibernate小例子
    [转载]mysql 学习笔记
    hibernate.cfg.xml 配置(摘录)
    j2ee笔试题目
    J2EE综合—Struts常见错误的全面汇总
    在Eclipse中写第一个hibernate小例子
    j2ee笔试题目
    hibernate.cfg.xml 配置(摘录)
    [转载]mysql 学习笔记
    J2EE综合—Struts常见错误的全面汇总
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6691301.html
Copyright © 2020-2023  润新知