SPOJ Hacking(字典树 + 搜索)题解
Posted kirinsb
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPOJ Hacking(字典树 + 搜索)题解相关的知识,希望对你有一定的参考价值。
思路1:字典树存每个串,然后dfs遍历是否存在。这里有个技巧,如果每次都重新初始化字典树为-1,那么会超时,所以我先初始化为-1,然后设一个Case,每个test时Case都++,那么只要开一个数组判断是否等于Case,如果等于就说明有这条路,不等则没有。这道题用字典树做要注意剪枝。
思路2:这道题能随机看命过
代码1:
#include<queue> #include<cstring> #include<set> #include<map> #include<stack> #include<cmath> #include<vector> #include<cstdio> #include<iostream> #include<algorithm> typedef long long ll; const int maxn = 1e4 + 10; const int seed = 131; const ll MOD = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; int n, m, k, length, Case; char s[maxn], ans[150]; int trie[maxn * 100][27], cs[maxn * 100][27], tot; void update(int st){ int p = 0; for(int i = 0; i < m; i++){ if(st + i > n) return; int v = s[st + i] - ‘a‘; if(v >= k) return; //剪枝 if(cs[p][v] != Case){ trie[p][v] = ++tot; cs[p][v] = Case; } p = trie[p][v]; } } bool dfs(int p, int len){ if(len > m) return false; for(int i = 0; i < k; i++){ if(cs[p][i] != Case){ ans[length++] = ‘a‘ + i; return true; } else if(dfs(trie[p][i], len + 1)){ ans[length++] = ‘a‘ + i; return true; } } return false; } int main(){ int t; Case = 0; memset(cs, -1, sizeof(cs)); scanf("%d", &t); while(t--){ Case++; tot = 0; scanf("%d%d%d", &n ,&m, &k); scanf("%s", s + 1); for(int i = 1; i <= n; i++){ update(i); } length = 0; dfs(0, 1); for(int i = length - 1; i >= 0; i--) printf("%c", ans[i]); printf(" "); } return 0; }
代码2:
#include<queue> #include<cstring> #include<set> #include<map> #include<stack> #include<string> #include<cmath> #include<vector> #include<cstdio> #include<iostream> #include<algorithm> typedef long long ll; const int maxn = 1e4 + 10; const int seed = 131; const ll MOD = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; int n, m, k; char s[maxn]; int main(){ int t; srand(time(NULL)); scanf("%d", &t); while(t--){ map<string, int> st; scanf("%d%d%d", &n ,&m, &k); scanf("%s", s + 1); for(int i = 1; i <= n - m + 1; i++){ string ss; for(int j = i; j < i + m; j++){ ss += s[j]; } st[ss] = 1; } string ans; while(true){ ans = ""; for(int i = 0; i < m; i++){ ans += ‘a‘ + rand() % k; } if(st[ans] == 0){ cout << ans << endl; break; } } } return 0; }
以上是关于SPOJ Hacking(字典树 + 搜索)题解的主要内容,如果未能解决你的问题,请参考以下文章
SPOJ COT Count on a tree(树上主席树 + LCA 求路径第k小)题解
SPOJ - QTREE Query on a tree题解