hdu 1251
题意:将一系列字符串插入字典中之后,查询给定的字符串是多少字符串的前缀。
思路:裸字典树
PS:很坑,用指针写无限MLE,只能用数组写了,不知道要开多大,一直照着内存改。
数组版本:
#include<bits/stdc++.h> using namespace std; const int maxn = 1e5 + 10; typedef long long ll; #define clr(x,y) memset(x,y,sizeof x) #define INF 0x3f3f3f3f const ll Mod = 1e9 + 7; typedef pair<ll,ll> P; char s[20]; int trie[maxn * 4][26]; int num[maxn * 4]; int tot = 1; void inserts(char* s) { int root = 1; for(int i = 0;s[i];i ++) { int x = s[i] - 'a'; if(trie[root][x] == 0) trie[root][x] = ++ tot; root = trie[root][x]; num[root] ++; } } int finds(char *s) { int root = 1; for(int i = 0;s[i];i ++) { int x = s[i] - 'a'; if(trie[root][x] == 0) return 0; root = trie[root][x]; } return num[root]; } int main() { bool flag = false; clr(trie,0);clr(num,0); while(gets(s)) { int len = strlen(s); if(len == 0) { flag = true;continue; } if(!flag) { inserts(s); } else { printf("%d\n",finds(s)); } } return 0; }
MLE的指针版本:
#include<bits/stdc++.h> using namespace std; const int maxn = 50000 + 10; typedef long long ll; #define clr(x,y) memset(x,y,sizeof x) #define INF 0x3f3f3f3f const ll Mod = 1e9 + 7; typedef pair<int,int> P; struct Trie { int cnt; Trie * next[26]; }* root; Trie* build() { Trie *t = new Trie(); memset(t -> next,NULL,sizeof(t -> next)); t -> cnt = 0; return t; } void inserts(char *s) { Trie *rt = root; while((*s)) { int x = (*s) - 'a'; if(rt -> next[x] == NULL) rt -> next[x] = build(); rt = rt -> next[x]; rt -> cnt ++; s ++; } } int finds(char *s) { Trie * rt = root; while((*s)) { int x = (*s) - 'a'; if(rt -> next[x] == NULL) rt -> next[x] = build(); rt = rt -> next[x]; s ++; } return rt -> cnt; } int main() { root = build(); bool flag = false; char s[10]; while(gets(s)) { int len = strlen(s); if(len == 0) { flag = true;continue; } if(!flag) { inserts(s); } else { printf("%d\n",finds(s)); } } return 0; }hdu 1247
题意:查询一个单词能够分成两部分,这两部分在字典中的单词。
思路:查询成两部分,在字典树中查询。主要查询的是出现过的单词,而不是单词前缀。
#include<bits/stdc++.h> using namespace std; const int maxn = 50000 + 10; typedef long long ll; #define clr(x,y) memset(x,y,sizeof x) #define INF 0x3f3f3f3f const ll Mod = 1e9 + 7; typedef pair<int,int> P; char s[maxn][20]; int trie[maxn * 4][26]; int tot = 1; int vis[maxn * 4]; void inserts(char* s) { int root = 1; for(int i = 0;s[i];i ++) { int x = s[i] - 'a'; if(trie[root][x] == 0) trie[root][x] = ++ tot; root = trie[root][x]; } vis[root] = 1; } int find2(char *s) { int root = 1; for(int i = 0;s[i];i ++) { int x = s[i] - 'a'; if(trie[root][x] == 0) return 0; root = trie[root][x]; } if(vis[root])return 1; return 0; } int find1(char *s) { int root = 1; for(int i = 0;s[i];i ++) { int x = s[i] - 'a'; if(trie[root][x] == 0) return 0; root = trie[root][x]; if( s[i + 1] && vis[root] && find2(s + i + 1)) return 1; } return 0; } int main() { int len = 0;clr(trie,0);clr(vis,0); while( ~ scanf("%s",s[++ len])){inserts(s[len]);} for(int i = 1;i <= len;i ++) { if(find1(s[i])) printf("%s\n",s[i]); } return 0; }