本文主要是介绍hihocoder 1260 String Problem I (Trie树 好题),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
-
3 3 tourist petr rng toosimple rg ptr
样例输出 -
0 1 1
描述
我们有一个字符串集合S,其中有N个两两不同的字符串。
还有M个询问,每个询问给出一个字符串w,求有多少S中的字符串可以由w添加恰好一个字母得到。
字母可以添加在包括开头结尾在内的任意位置,比如在"abc"中添加"x",就可能得到"xabc", "axbc", "abxc", "abcx".这4种串。
输入
第一行两个数N和M,表示集合S中字符串的数量和询问的数量。
接下来N行,其中第i行给出S中第i个字符串。
接下来M行,其中第i行给出第i个询问串。
所有字符串只由小写字母构成。
数据范围:
N,M<=10000。
S中字符串长度和<=100000。
所有询问中字符串长度和<=100000。
输出
对每个询问输出一个数表示答案。
题目链接:http://hihocoder.com/problemset/problem/1260
题目分析:感觉正解不是Trie但是还是用Trie搞过了,其实就是在trie树上DFS的时候有一个点可以“失配”而直接跳到下一层,Search(char *s, int pos, int p, bool ok),s表示要查询的字符串,pos表示枚举到s的第pos位,p表示当前父亲编号,ok表示之前是否已经跳过一次,true表示没跳过,这里有个问题就是比如
2 1
aa
ab
a
错误答案跑出来会是3,因为对于aa来说,他先跳和后跳的情况都被计算了,因此还需要记录一个单词是否已经满足情况,由于点的个数太多但是n比较小,所以考虑将单词结尾标号用map离散化,还有一点要注意的就是当pos==len的时候不能直接return,因为有可能在最后一个单词那里跳,比如
1 1
ab
b
所以当pos==len时要先判断跳不跳,再return
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
int const MAX = 1e5 + 5;
int n, m, ans, len;
char s[MAX];struct Trie
{int next[MAX * 26][26], end[MAX * 26], tot, root, num;bool vis[10005];map <int, int> mp;inline int Newnode(){memset(next[tot], -1, sizeof(next[tot]));end[tot] = false;return tot ++;} inline void Init(){num = 0;tot = 0;root = Newnode();}inline void Insert(char *s){int p = root;for(int i = 0; i < (int)strlen(s); i++){int idx = s[i] - 'a';if(next[p][idx] == -1)next[p][idx] = Newnode();p = next[p][idx];}end[p] = true;mp[p] = num ++;}inline void Search(char *s, int pos, int p, bool ok){if(end[p] && !vis[mp[p]] && pos == len){vis[mp[p]] = true;ans ++;return;}if(ok)for(int i = 0; i < 26; i++)if(next[p][i] != -1)Search(s, pos, next[p][i], false);if(pos == len)return;int idx = s[pos] - 'a';if(next[p][idx] != -1)Search(s, pos + 1, next[p][idx], ok);}}t;int main()
{t.Init();scanf("%d %d",&n, &m);for(int i = 0; i < n; i++){scanf("%s", s);t.Insert(s);}for(int i = 0; i < m; i++){scanf("%s", s);ans = 0;len = strlen(s);memset(t.vis, false, sizeof(t.vis));t.Search(s, 0, t.root, true);printf("%d\n", ans);}
}
这篇关于hihocoder 1260 String Problem I (Trie树 好题)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!