链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2846
题目:
20 ad ae af ag ah ai aj ak al ads add ade adf adg adh adi adj adk adl aes 5 b a d ad s
0 20 11 11 2
分析与总结:
Trie树的应用。
对于每个单词, 把他的所有字串插入字符串,并在相应的位置+1. 注意一个单词如果有多个相同的字串,那这个字串也只能加一次。所有节点要多一个变量用来标记是否已经加过。
这个过程只需要枚举单词的开始位置,然后插入Trie树即可。
然后查询直接找出相应单词在Trie树中记录的数量即可。
代码:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int KIND = 26; const int MAXN = 5000000; int cnt_node; struct node{ int flag; // 标记是否已经加过了 int cnt; // 记录以这个单词为字串的有多少个商品 node* next[KIND]; void init(){ flag=-10; cnt=0; memset(next, 0, sizeof(next)); } }Heap[MAXN]; inline node* new_node(){ Heap[cnt_node].init(); return &Heap[cnt_node++]; } inline void insert(node *root, char *str, int flag){ for(char *p=str; *p; ++p){ int ch=*p-'a'; if(root->next[ch]==NULL) root->next[ch]=new_node(); root = root->next[ch]; if(root->flag!=flag){ root->flag=flag; ++root->cnt; } } } inline int get_count(node* root, char* str){ for(char *p=str; *p; ++p){ int ch=*p-'a'; if(root->next[ch]==NULL) return 0; root = root->next[ch]; } return root->cnt; } int main(){ int p; char str[25]; scanf("%d",&p); // Trie init cnt_node=0; node *root = new_node(); while(p--){ scanf("%s",str); char tmp[25]; int len=strlen(str); for(int i=0; i<len; ++i){ insert(root, str+i, p); } } scanf("%d",&p); while(p--){ scanf("%s",str); printf("%d\n", get_count(root, str)); } return 0; }
—— 生命的意义,在于赋予它意义士。
原创 http://blog.csdn.net/shuangde800 , By D_Double (转载请标明)