Hdu 3065 病毒侵袭持续中(AC自动机)

来源:互联网 发布:淘宝客帐号怎么注册 编辑:程序博客网 时间:2024/06/18 06:59

病毒侵袭持续中
Time Limit: 2000 Memory Limit: 32768
Problem Description
小t非常感谢大家帮忙解决了他的上一个问题。然而病毒侵袭持续中。在小t的不懈努力下,他发现了网路中的“万恶之源”。这是一个庞大的病毒网站,他有着好多好多的病毒,但是这个网站包含的病毒很奇怪,这些病毒的特征码很短,而且只包含“英文大写字符”。当然小t好想好想为民除害,但是小t从来不打没有准备的战争。知己知彼,百战不殆,小t首先要做的是知道这个病毒网站特征:包含多少不同的病毒,每种病毒出现了多少次。大家能再帮帮他吗?
Input
第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。
接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。
在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。
Output
按以下格式每行一个,输出每个病毒出现次数。未出现的病毒不需要输出。
病毒特征码: 出现次数
冒号后有一个空格,按病毒特征码的输入顺序进行输出。
Sample Input
3
AA
BB
CC
ooxxCC%dAAAoen….END
Sample Output
AA: 2
CC: 1
Hint
Hit:
题目描述中没有被提及的所有情况都应该进行考虑。比如两个病毒特征码可能有相互包含或者有重叠的特征码段。
计数策略也可一定程度上从Sample中推测。
Source
2009 Multi-University Training Contest 16 - Host by NIT

/*这题不是1A.吐槽一下:又是多组输入.有几个点需要注意一下.这题是不需要用mark判重的,这点没想到.还有出现不合法字符的时候要指针要指到root.不然就认为是忽略了不合法字符把两边连接起来了.*/#include<iostream>#include<cstring>#include<cstdio>#include<queue>#define MAXN 50010#define MAXM 2000010using namespace std;int n,m,l,tot=1,a[1001],fail[MAXN];char s[MAXM],ch[1001][52];struct data{int x[27],b;}tree[MAXN];queue<int>q;void add(int t){    l=strlen(s+1);int now=1;    for(int i=1;i<=l;i++)    {        int x=s[i]-64;        if(!tree[now].x[x]) tree[now].x[x]=++tot;        now=tree[now].x[x];    }    tree[now].b=t;    return ;}void get_fail(){    for(int i=1;i<=26;i++) tree[0].x[i]=1;    q.push(1);    while(!q.empty())    {        int now=q.front();q.pop();        for(int i=1;i<=26;i++)        {            if(!tree[now].x[i]) continue;            int k=fail[now];            while(!tree[k].x[i]) k=fail[k];            k=tree[k].x[i];            fail[tree[now].x[i]]=k;            q.push(tree[now].x[i]);        }    }    return ;}void Mark(){    int now=1;l=strlen(s+1);    for(int i=1;i<=l;i++)    {        if(s[i]<'A'||s[i]>'Z') {now=1;continue;}        int x=s[i]-64;        while(!tree[now].x[x]) now=fail[now];        now=tree[now].x[x];        int k=now;        while(k)        {            if(tree[k].b) a[tree[k].b]++;            k=fail[k];        }    }    return ;}void Clear(){    memset(ch,0,sizeof ch);// 1 w.    memset(fail,0,sizeof fail);    memset(a,0,sizeof a);    memset(tree,0,sizeof tree);    tot=1;}int main(){    while(scanf("%d",&n)!=EOF)    {        Clear();        for(int i=1;i<=n;i++)        {            scanf("%s",s+1),add(i);            for(int j=1;j<=strlen(s+1);j++) ch[i][j]=s[j];        }        get_fail();        scanf("%s",s+1);        Mark();        for(int i=1;i<=n;i++)          if(a[i]) printf("%s: %d\n",ch[i]+1,a[i]);    }    return 0;}
0 0
原创粉丝点击