• HDU1251-统计难题(字典树)


    统计难题

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


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

    注意:本题只有一组测试数据,处理到文件结束.
     
    Output
    对于每个提问,给出以该字符串为前缀的单词的数量.
     
    Sample Input
    banana band bee absolute acm ba b band abc
     
    Sample Output
    2 3 1 0
     
    裸的字典树,留个板子。喜欢用数组建树,不喜欢指针。QAQ
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <cmath>
     6 using namespace std;
     7 const int maxn = 5e5+5;
     8 struct node
     9 {
    10     int next[30];
    11     int v;
    12 };
    13 int sz = 1;
    14 node tree[maxn];
    15 void init()
    16 {
    17     sz = 1;
    18     memset(tree[0].next,0,sizeof(tree[0].next));
    19     tree[0].v = 0;
    20 }
    21 void build(char s[])
    22 {
    23     int root = 0;
    24     int n = strlen(s);
    25     for(int i=0;i<n;i++)
    26     {
    27         int id = s[i]-'a';
    28         if(tree[root].next[id]==0)
    29         {
    30             memset(tree[sz].next,0,sizeof(tree[sz].next));
    31             tree[sz].v = 0;
    32             tree[root].next[id] = sz++;
    33         }
    34         root = tree[root].next[id];
    35         tree[root].v += 1;
    36     }
    37 }
    38 void match(char s[])
    39 {
    40     int ans = 0,root = 0;
    41     int n = strlen(s);
    42     int flag = 0;
    43     for(int i=0;i<n;i++)
    44     {
    45         int id = s[i]-'a';
    46         if(tree[root].next[id])
    47         {
    48             root = tree[root].next[id];
    49             ans = tree[root].v;
    50         }
    51         else
    52         {
    53             flag = 1;
    54             break;
    55         }
    56     }
    57     if(!flag) printf("%d
    ",ans);
    58     else printf("0
    ");
    59 }
    60 int main()
    61 {
    62     init();
    63     char s[20];
    64     while(gets(s)&&s[0]!='')
    65     {
    66         build(s);
    67     }
    68     while(scanf("%s",s)!=EOF)
    69     {
    70         match(s);
    71     }
    72     return 0;
    73 }
     
  • 相关阅读:
    左旋一个字符串和手摇反转法
    LCS
    游戏服务器学习_1
    面试题_带答案_2
    面试题_带答案
    安卓_13
    安卓_12activity
    安卓_12
    多盟_1
    安卓没删干净导致报错
  • 原文地址:https://www.cnblogs.com/littlepear/p/5819312.html
Copyright © 2020-2023  润新知