hdu

模版题。。。。注意只统计总类

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<queue>
#define val 10005
using namespace std;

struct Dictree
{
	int cnt;
	int no;
	Dictree *next[100],*fail;
}*root;
vector<int> hack;
queue<Dictree *> q;
int n,m;
bool flag;
int mark[val];
char s[val],p[val];
void built_tree();
void set_fail();
void ac_auto(char *);
void empty_tree(Dictree *);
int main()
{
	int i,j,cnt;
	while(scanf("%d",&n)!=EOF)
	{
		getchar();
		built_tree();
		set_fail();
		cnt=0;
		scanf("%d",&m);
		getchar();
		for(i=1;i<=m;i++)
		{
			gets(s);
			hack.clear();
			flag=false;
			memset(mark,false,sizeof(mark));
			ac_auto(s);
			cnt+=flag;
			if(flag)
			{
				printf("web %d:",i);
				for(j=1;j<=n;j++)
					if(mark[j]) printf(" %d",j);
				putchar('\n');
			}
		}
		printf("total: %d\n",cnt);
		empty_tree(root);
	}
	return 0;
}
void built_tree()
{
	void insert(char *,int );
	int i;
	root=(Dictree*)malloc(sizeof(Dictree));
	root->no=0;
	root->fail=NULL;
	root->cnt=0;
	memset(root->next,NULL,sizeof(root->next));
	for(i=0;i<n;i++)
	{
		gets(s);
		insert(s,i+1);
	}
}
void insert(char *s,int key)
{
	int i;
	Dictree *t,*p=root;
	for(i=0;s[i];i++)
	{
		if(p->next[s[i]-32]==NULL)
		{
			t=(Dictree *)malloc(sizeof(Dictree));
			t->cnt=0;
			t->no=0;
			t->fail=NULL;
			memset(t->next,NULL,sizeof(t->next));
			p->next[s[i]-32]=t;
		}
		p=p->next[s[i]-32];
	}
	p->cnt++;
	p->no=key;
}
void set_fail()
{
	int i;
	Dictree *p,*temp;
	q.push(root);
	while(!q.empty())
	{
		p=q.front();
		q.pop();
		for(i=0;i<100;i++)
		{
			if(p->next[i])
			{
				if(p==root)   	p->next[i]->fail=root;
				else
				{
					temp=p->fail;
					while(temp)
					{
						if(temp->next[i])
						{
							p->next[i]->fail=temp->next[i];
							break;
						}
						temp=temp->fail;
					}
					if(temp==NULL) p->next[i]->fail=root;
				}
				q.push(p->next[i]);
			}
		}
	}
}
void ac_auto(char *s)
{
	int i,index;
	Dictree *p=root,*temp;
	for(i=0;s[i];i++)
	{
		index=s[i]-32;
		while(p!=root)
		{
			if(p->next[index]) break;
			p=p->fail;
		}
		temp=p=p->next[index];
		if(p==NULL) temp=p=root;
		while(temp)
		{
			if(temp->cnt)
			{
				flag=true;
				mark[temp->no]=true;
				hack.push_back(temp->no);
			}
			temp=temp->fail;
		}
	}
}
void empty_tree(Dictree *p)
{
	int i;
	for(i=0;i<26;i++)
		if(p->next[i])  empty_tree(p->next[i]);
	free(p);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值