hdu 2896 病毒侵袭

来源:互联网 发布:程序员新人第一天 编辑:程序博客网 时间:2024/06/02 20:36

本题需要注意几个方面:

1、字符的范围是可见的ASCLL码字符,数组要开到127。

2、虽然题目的数据弱了,但是自己要考虑的周全。

数据一:

2sherhe2shesher
答案:

web 1: 2web 2: 1 2total: 2
数据二:

2aaa1aaaa
答案:

web 1: 1 2total: 1

#include"cstdlib"#include"cstdio"#include"cstring"#include"cmath"#include"queue"#include"algorithm"#include"iostream"using namespace std;struct trie{    int mark;    trie *fail;    trie *next[130];    trie()    {        mark=0;        fail=NULL;        memset(next,0,sizeof(next));    }};trie *root;void init(char *v,int id){    int i;    trie *p=root;    for(i=0; v[i]; i++)    {        int tep=v[i];        if(p->next[tep]==NULL)  p->next[tep]=new trie();        p=p->next[tep];    }    p->mark=id;}void getac(){    queue<trie*>q;    q.push(root);    while(!q.empty())    {        int i;        trie *p,*tep;        p=q.front();        q.pop();        for(i=0; i<128; i++)        {            if(p->next[i]!=NULL)            {                if(p==root)  p->next[i]->fail=root;                else                {                    tep=p->fail;                    while(tep!=NULL)                    {                        if(tep->next[i]!=NULL)                        {                            p->next[i]->fail=tep->next[i];                            break;                        }                        tep=tep->fail;                    }                    if(tep==NULL) p->next[i]->fail=root;                }                q.push(p->next[i]);            }        }    }}int finde(char *v,int *ans){    int i,k=0;    trie *p=root,*q;    for(i=0; v[i]; i++)    {        int tep=v[i];        while(p->next[tep]==NULL && p!=root)            p=p->fail;        p=p->next[tep];        if(p==NULL)  p=root;        q=p;        while(q!=root)   //把每个都匹配过去,因为题目说了最多只有三种不同的!        {            if(q->mark!=0)  ans[k++]=q->mark;            q=q->fail;        }    }    return k;}void del(trie *p){    for(int j=0; j<26; j++) if(p->next[j]!=NULL) del(p->next[j]);    free(p);}int main(){    int n,m;    while(scanf("%d",&n)!=-1)    {        int i,j;        root=new trie();        getchar();        for(i=1; i<=n; i++)        {            char v[202];            gets(v);            init(v,i);        }        getac();        scanf("%d",&m);        getchar();        int cont=0;        for(i=1; i<=m; i++)        {            char x[10005];            int ans[10];            memset(ans,0,sizeof(ans));            gets(x);                int k=finde(x,ans);            if(k)            {                printf("web %d:",i);                sort(ans,ans+k);                for(j=0; j<k; j++)                {                    if(ans[j]!=ans[j+1])  printf(" %d",ans[j]);  //为了去重                }                puts("");                cont++;            }        }        printf("total: %d\n",cont);        del(root);    }}


0 0