标签:acm repository hdu2846 字典树 字典树的一种变形
20 ad ae af ag ah ai aj ak al ads add ade adf adg adh adi adj adk adl aes 5 b a d ad s
0 20 11 11 2
我的AC状态,,我总感觉自己好笨的。。脑子不太灵活,第一次写的时候超时了,,来说一下思路吧,,就是把一个字符串abcde,分别拆成abcde,bcde,cde,de,e,存到字典树里,因为会出现会abcab这样的字符串,他的字串有俩个ab开头的,,所以得在结构体里加上一个id标签,,把id设为最后一个存到字典树里的字符串。看代码就知道啦,很容易懂的
下面是AC代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 20000
struct Trie{
int count; //储存相同字符串的数目
int id ; //标识已储存过的字符串,防止重复计算。
Trie *next[26];
};
//建树
void build(Trie *t , char name[] , int id)
{
int len =strlen(name) ;
for(int i = 0 ; i < len; ++i)
{
if(t->next[name[i]-'a'] == NULL)
{
Trie *temp = (Trie*)malloc(sizeof(Trie)) ;
temp->count=1;
temp->id = id ;
for(int j = 0 ; j < 26 ; ++j)
{
temp->next[j] = NULL ;
}
t->next[name[i]-'a'] = temp ;
t = temp ;
}
else
{
t = t->next[name[i]-'a'] ;
if(id != t->id)
t->count ++;
t->id = id ;
}
}
}
int count = 0 ;
bool flag[MAX] ;
//查询
void query(Trie *t , char str[])
{
int len = strlen(str) , i ;
for(i = 0 ; i < len ; ++i)
{
if(t->next[str[i]-'a'] != NULL)
{
t = t->next[str[i]-'a'] ;
}
else
{
break ;
}
}
if( i == len )
{
if(!flag[t->id])
{
count += t->count ;
flag[t->id] = true ;
}
}
}
int main()
{
int n ;
scanf("%d",&n);
Trie *t=(Trie *)malloc(sizeof(Trie));
for(int i = 0 ; i < 26 ; ++i)
{
t->next[i] = NULL ;
}
t->count = 0 ;
for(int i =0 ; i < n ; ++i)
{
char name[30];
scanf("%s",name) ;
int len = strlen(name) ;
for(int j = 0 ; j < len ; ++j)
{
build(t,name+j,i);
}
}
int q;
scanf("%d",&q);
for(int i = 0 ; i < q ; ++i)
{
memset(flag,0,sizeof(flag)) ;
char str[30];
count = 0 ;
scanf("%s",str);
query(t,str) ;
printf("%d\n",count) ;
}
return 0 ;
}
下面是第一次超时的代码,,大家可以无视跳过。。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Trie{
int count;
Trie *next[26];
};
void build(Trie *t , char name[])
{
int len =strlen(name) ;
for(int i = 0 ; i < len; ++i)
{
if(t->next[name[i]-'a'] == NULL)
{
Trie *temp = (Trie *)malloc(sizeof(Trie)) ;
temp->count=1;
for(int j = 0 ; j < 26 ; ++j)
{
temp->next[j] = NULL ;
}
t->next[name[i]-'a'] = temp ;
t = temp ;
}
else
{
t = t->next[name[i]-'a'] ;
t->count ++;
}
}
}
int count = 0 ;
void query(Trie *t , char str[],int index)
{
if(index == strlen(str))
{
count += t->count ;
return ;
}
for(int i = 0 ; i < 26 ; ++i)
{
if(t->next[i] != NULL)
{
if(i == str[index]-'a')
{
query(t->next[i],str,index+1);
}
else
{
query(t->next[i],str,0) ;
}
}
}
}
void destroy(Trie *t)
{
for(int i = 0 ; i < 26 ; ++i)
{
if(t->next[i] != NULL)
destroy(t->next[i]) ;
}
free(t);
}
int main()
{
int n ;
scanf("%d",&n);
Trie *t=(Trie *)malloc(sizeof(Trie));
for(int i = 0 ; i < 26 ; ++i)
{
t->next[i] = NULL ;
}
t->count = 0 ;
for(int i =0 ; i < n ; ++i)
{
char name[30];
scanf("%s",name) ;
build(t,name);
}
int q;
scanf("%d",&q);
for(int i = 0 ; i < q ; ++i)
{
char str[30];
count = 0 ;
scanf("%s",str);
query(t,str,0) ;
printf("%d\n",count) ;
}
destroy(t) ;
return 0 ;
}下面是正确的代码
标签:acm repository hdu2846 字典树 字典树的一种变形
原文地址:http://blog.csdn.net/lionel_d/article/details/43449471