HDU1251 统计难题【字典树】

统计难题

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


Problem Description
Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).
 

Input
输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.

注意:本题只有一组测试数据,处理到文件结束.
 

Output
对于每个提问,给出以该字符串为前缀的单词的数量.
 

Sample Input
 
  
bananabandbeeabsoluteacmbabbandabc
 

Sample Output
 
  
2310

问题链接HDU1251 统计难题

问题描述

  输入若干小写字母组成的字符串集合,然后是一个空行;再输入若干字符串,计算这些字符串作为前缀出现的次数。

问题分析

  这个问题是字典树的裸题。

  需要注意空间的大小!

程序说明:(略)

参考链接:(略)

题记(略)


AC的C++语言程序如下:

/* HDU1251 统计难题  */

#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

const int N = 100000;
const int LEN = 10;
const int SIZE = 26;
const char SCHAR = 'a';

struct Trie {
    int acnt;   // access count
    int childs[SIZE];
    void init()
    {
        acnt = 1;
        memset(childs, 0, sizeof(childs));
    }
} trie[N * LEN];
int ncnt;   // Trie Node count
char s[LEN + 1]; // Input

void insert(char s[])
{
    int p = 0;
    for(int i = 0; s[i]; i++) {
        int k = s[i] - SCHAR;
        int child = trie[p].childs[k];
        if(child) {
            trie[child].acnt++;
            p = child;
        } else {
            trie[++ncnt].init();
            trie[p].childs[k] = ncnt;
            p = ncnt;
        }
    }
}

int query(char s[])
{
    int p = 0;
    for (int i = 0; s[i]; i++) {
        int k = s[i] - SCHAR;
        int child = trie[p].childs[k];
        if (child == 0)
            return 0;
        else
            p = child;
    }
    return trie[p].acnt;
}

int main()
{
    while(gets(s)) {
        if(s[0] == NULL)
            break;
        insert(s);
    }

    while(gets(s))
        printf("%d\n", query(s));

    return 0;
}







猜你喜欢

转载自blog.csdn.net/tigerisland45/article/details/80956218