hdu 2846

字典树的变形,常规字典树用来求前缀的,所以把每个单词拆成len个词建树,为了避免abab这样的查ab时会出现两次,每次加一个标记,如果该节点上次的建树的单词与本次相同就不更新,否则更新




 

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

struct tree

{

	struct tree *son[26];

	int count;

	int flag;

}*root;

void insert(char *p,int id)

{

	int i,k,j;

	tree *cur=root,*next;

    int len=strlen(p);

	for(i=0;i<len;i++)

	{

		k=p[i]-'a';

		if(cur->son[k]!=NULL)

			cur=cur->son[p[i]-'a'];

		else 

		{

			next=new(tree);

			for(j=0;j<26;j++)

				next->son[j]=NULL;

			next->count=0;

			next->flag=-1;

			cur->son[p[i]-'a']=next;

			cur=next;

		}

		if(cur->flag!=id)//如果上次在该节点更新的单词与本次单词不同就更新

		{

			cur->count++;	

			cur->flag=id;

		}

	}	

}

int find(char *p)  

{  

    int i;  

    tree *cur=root;  

    int len=strlen(p);  

    for(i=0;i<len;i++)  

    {  

        int k=p[i]-'a';  

        if(cur->son[k]==NULL)  

            break;  

        else cur=cur->son[k];  

    } 

	if(i<len) return 0;

	return cur->count;  

}  

int main()

{

	int i,j,n,m;

	char s[25];

	root=new(tree);  

	for(i=0;i<26;i++)

		root->son[i]=NULL;

	root->count=0;

	root->flag=-1;

	scanf("%d",&n);

	for(i=1;i<=n;i++)

	{

		scanf("%s",s);

		for(j=0;s[j];j++)

		{

			insert(s+j,i);//拆单词建树

		}

	}

	scanf("%d",&m);

	while(m--)

	{

		scanf("%s",s);

		j=find(s);

		printf("%d\n",j);

	}

	return 0;

}


 


 

你可能感兴趣的:(HDU)