统计难题
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;
}