题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2846
题目:输入个n个词典串,然后输入q个串,对这q个串分别输出每个串都是几个词典串的子串。
思路:因为要包含子串,比如abd,将串abd,bd,d都插入字典树,然后每个节点下统计子树个数,直接查找前缀就可以了。但需要注意dcda这种的,需要插入dcda,cda,da,a,这个时候d下面的子树应该是一个而不是2个,因为dcda和da属于同一个词典串。所以在插入的时候进行处理即可。
代码
#include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #include <string> #include <vector> using namespace std; #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 #define ceil(x, y) (((x) + (y) - 1) / (y)) const int SIZE = 30; const int N = 1e6 + 10; const int INF = 0x7f7f7f7f; struct Trie { int val[SIZE]; int t; int count; }; int sz; Trie pn[N]; int newnode() { memset(pn[sz].val, 0, sizeof(pn[sz].val)); pn[sz].count = pn[sz].t = 0; return sz++; } void init() { sz = 0; newnode(); } void insert(char *s, int t, int c) { int u = 0; for (int i = t; s[i]; i++) { int idx = s[i] - 'a'; if (!pn[u].val[idx]) { pn[u].val[idx] = newnode(); } u = pn[u].val[idx]; if (pn[u].t != c) { pn[u].count++; pn[u].t = c; } } } int findpre(char *s) { int u = 0; for (int i = 0; s[i]; i++) { int idx = s[i] - 'a'; if (!pn[u].val[idx]) return 0; u = pn[u].val[idx]; } return pn[u].count; } int main() { int n, q; char str[SIZE]; while (scanf("%d", &n) != EOF) { init(); for (int i = 1; i <= n; i++) { scanf("%s", str); for (int j = 0; str[j]; j++) insert(str, j, i); } scanf("%d", &q); for (int i_q = 1; i_q <= q; i_q++) { scanf("%s", str); printf("%d\n", findpre(str)); } } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-31 20:51:24