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;
}