hdu 2846霸气的字典树

Repository
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1385    Accepted Submission(s): 487


Problem Description
When you go shopping, you can search in repository for avalible merchandises by the computers and internet. First you give the search system a name about something, then the system responds with the results. Now you are given a lot merchandise names in repository and some queries, and required to simulate the process.


Input
There is only one case. First there is an integer P (1<=P<=10000)representing the number of the merchanidse names in the repository. The next P lines each contain a string (it's length isn't beyond 20,and all the letters are lowercase).Then there is an integer Q(1<=Q<=100000) representing the number of the queries. The next Q lines each contains a string(the same limitation as foregoing descriptions) as the searching condition.


Output
For each query, you just output the number of the merchandises, whose names contain the search string as their substrings.


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



Sample Output

0
20
11
11
2


题意是给你p个源字符串,然后询问Q个目的字符串,询问每个目的字符串时,要你从p个源字符串中找出包含目的字符串的个数。注意当第i个字符串中含有多个目的字符串时,只当作一个。比如源串为ababab abcd 目的串为ab,则输出结果为2,而不是4.所以在建的时候要进行id的判断。此题在传统的建树上面作了变通:比如对字符串abcd进行建树时,不仅要对abcd,还要对bcd,cd,d都进行建树,因为此题中的子串可能是开头,中间或者结尾,所以这样建有利于最后的询问,节省时间。


/*防止重复计算  例如:ababababc ab重复出现了好多次 建立ababababc ab出现了一次 建立abababc ab有出现了一次 建立ababc abc 均出现
这时候本来应该算作是一次的
那么当我们建立了ababababc  再次建立abababc的时候 我们前面要走相同的路线 那么这2个子串是在同一个串中 所以次数就没必要增加了
所以用id标记是否属于同一个字符串 防止重复计算出现次数

*/

#include<stdio.h>
#include<string.h>
#include<malloc.h>
struct haha
{
	int cnt;
	int id;//标记第几个字符串的  防止重复计算 防止重复出现某个串 比如ababababc ab重复出现了好多次
	struct haha *next[26];
}*root;
int ans;
struct haha * creat()
{
	int i;
	struct haha *p;
	p=(struct haha *)malloc(sizeof(struct haha));
	p->cnt=1;
	p->id=-1;
	for(i=0;i<26;i++)
		p->next[i]=NULL;
	return p;
}
void update(char *s,int id)
{
	int d,pos,i;
	struct haha *p;
	p=root;
	d=strlen(s);
	for(i=0;i<d;i++)
	{
        pos=s[i]-'a';
		if(p->next[pos]==NULL)
		{
			p->next[pos]=creat();
			p=p->next[pos];
			p->id=id;
		}
		else
		{
			p=p->next[pos];
			if(p->id!=id)//也就是说这个串的子串没有出现过
			{
				p->id=id;
				p->cnt++;
			}
		}
	} 
}
void query(char *s)
{
	struct haha *p;
	int pos,i,d;
	p=root;
	d=strlen(s);
	for(i=0;i<d;i++)
	{
		pos=s[i]-'a';
		if(p->next[pos]==NULL) return ;
		else
		{
			p=p->next[pos];
		}
	}
	ans=p->cnt;
}
int main()
{
	int i,n,m,k;
	char s[30];
	root=creat();
    scanf("%d",&n);
	for(k=0;k<n;k++)
	{
		scanf("%s",s);
		for(i=0;s[i]!='\0';i++)
			update(&s[i],k);
	}
	scanf("%d",&m);
	while(m--)
	{
		ans=0;
		scanf("%s",s);
		query(s);
		printf("%d\n",ans);
	}
	return 0;
}



你可能感兴趣的:(hdu 2846霸气的字典树)