zoukankan      html  css  js  c++  java
  • HDU

    题目:

    统计难题

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)
    Total Submission(s): 14095    Accepted Submission(s): 6070


    Problem Description
    Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).
     
    Input
    输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.

    注意:本题只有一组测试数据,处理到文件结束.
     
    Output
    对于每个提问,给出以该字符串为前缀的单词的数量.
     
    Sample Input
    banana
    band
    bee
    absolute
    acm
     
    ba
    b
    band
    abc
     
    Sample Output
    2
    3
    1
    0
     
      题意不解释,这题RE+MLE+WA一共16次= =,主要是对Trie不太熟悉。首先我用的是静态链表,RE的主要原因是数组成二维了,这一点一开始没有考虑到,是因为没有仔细把大白书上面的模板看完,以为用来标记的数组应该也是二维的,这样才合逻辑,虽然小数据的话没有出问题,但是数据大到一定情况的话就会RE,这是就会认为是不是数组开得不够大,于是继续加大,接着就是MLE了= =。
      用来标记的附加数组这里只需要使用一维的就可以,为什么?因为这里字典树的本体用的是一个二维数组,其中一维是用来表示某个前缀的下一个字母有可能是哪些(这里这种解释似乎有点不是很准确,建议去看一下Trie树的构成),另一维是用来表示可以最多可以保存多少个字母的长度(这种说法也好像不是很准确)。附加数组的规模需要和字典树的另一维一样大,这样才可以起作用。其实就是把静态链表的结构看成指针链表(就是把原本整齐的内存结构看成游离的内存块,这样说似乎更加生动,容易理解= =) 那么附加数组就像是紧贴Trie数的一条链,它的作用就是标明某个位置就是一个字符串的结束,就像字符串末尾的''一样。
      至于上面说的规模需要开多大,我觉得这里需要根据问题来决定,如果他说有10000个字符串,每个字符串最长就有10的长度,每个位置有10种字符出现的可能的话,规模大概就需要10000*10*10以上了,这里我暂时还不是很确定,有可能可以小一点。
     
     
     
    代码:
     1 #include <stdio.h>
     2 #include <string.h>
     3 #define MAX 500000
     4 using namespace std;
     5 
     6 int s[MAX][26],count[MAX],tot;
     7 
     8 void Init()
     9 {
    10     memset(s[0],0,sizeof(s[0]));
    11     memset(count,0,sizeof(count));
    12     tot=1;
    13 }
    14 
    15 void Insert(char *c)
    16 {
    17     int i,j,u,n;
    18     n=strlen(c);
    19     j=0;
    20     for(i=0;i<n;i++)
    21     {
    22         u=c[i]-'a';
    23         if(!s[j][u])
    24         {
    25             memset(s[tot],0,sizeof(s[tot]));
    26             count[tot]=0;
    27             s[j][u]=tot++;
    28         }
    29         j=s[j][u];
    30         count[j]++;
    31     }
    32 }
    33 
    34 
    35 int Query(char *c)
    36 {
    37     int i,j,u,n;
    38     n=strlen(c);
    39     j=0;
    40     if(n>20) return 0;
    41     for(i=0;i<n;i++)
    42     {
    43         u=c[i]-'a';
    44         if(!s[j][u]) return 0;
    45         if(i+1==n) break;
    46         j=s[j][u];
    47     }
    48     return count[s[j][u]];
    49 }
    50 
    51 int main()
    52 {
    53     int ans;
    54     char c[100];
    55     Init();
    56     while(gets(c),c[0]!='')
    57     {
    58         Insert(c);
    59     }
    60     while(gets(c))
    61     {
    62         ans=Query(c);
    63         printf("%d
    ",ans);
    64     }
    65     return 0;
    66 }
    1251
  • 相关阅读:
    云之家技术文档下载
    原始MAC地址
    如何创建数据中心
    获取金蝶云试用许可
    【分享】工作流支持邮件提醒相关配置
    调试K3网页版需要注意的问题
    excel2010冻结行列
    Delphi 泛型 接口约束的实例 转
    delphi 各新版本特性收集
    Delphi XE Refactor重构功能简单说明 转
  • 原文地址:https://www.cnblogs.com/sineatos/p/3296858.html
Copyright © 2011-2022 走看看