HDU 3065 简单题
题意 就是N个病毒,一个 匹配串,然后让你从这匹配串里面去找病毒出现的次数;
方法 如果匹配 则往下走,如果不匹配,或者没有字符越界,回到根节点;
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;
struct date
{
date *next[26],*fail;
int tab;
}tree[51234],*que[51234],*root;
int tail,head,ptr,res[1123];
char str[2123456],sss[2123456],cha[1123][55];
date *creat_node( )
{
for( int i = 0; i < 26; i++ )
tree[ptr].next[i] = NULL;
tree[ptr].fail = NULL;
tree[ptr].tab = 0;
return &tree[ptr++];
}
void inint( )
{
tail = head = ptr = 0;
root = creat_node();
}
void insert( char *word,int tab )
{
date *temp = root;
while( *word )
{
int num = *word - 'A';
if( temp->next[num] == NULL )
temp->next[num] = creat_node();
temp = temp->next[num];
word++;
}
temp->tab = tab;
}
void build_AC( )
{
que[tail++] = root;
while( tail > head )
{
date *temp = que[head++];
for( int i = 0; i < 26; i++ )
if( temp->next[i] != NULL )
{
if( temp == root ) temp->next[i]->fail = root;
else temp->next[i]->fail = temp->fail->next[i];
que[tail++] = temp->next[i];
}
else
{
if( temp == root ) temp->next[i] = root;
else temp->next[i] = temp->fail->next[i];
}
}
}
void query( char *word )
{
date *patten,*temp = root;
while( *word )
{
int num = *word - 'A';
if( num < 0 || num > 25 )
{
temp = root;word++;
continue;
}
temp = temp->next[num];
patten = temp;
while( patten != root )
{
if( patten->tab )
res[patten->tab]++;
patten = patten->fail;
}
word++;
}
}
int main( )
{
int N,i,t;
while( scanf("%d",&N) != EOF )
{
inint();
for( i = 1; i <= N; i++ )
{
scanf("%s",&cha[i]);
insert( cha[i],i );
}
build_AC();
scanf("%s",&sss);
memset( res,0,sizeof(res) );
query( sss );
for( i = 1; i <= N; i++ )
if( res[i] ) printf("%s: %d\n",cha[i],res[i]);
}
return 0;
}
浙公网安备 33010602011771号