HDU3695 Computer Virus on Planet Pandora

来源:互联网 发布:大数据平台的数据交换 编辑:程序博客网 时间:2024/05/16 12:46

题目链接:HDU3695

Computer Virus on Planet Pandora

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 256000/128000 K (Java/Others)
Total Submission(s): 3727    Accepted Submission(s): 984


Problem Description
    Aliens on planet Pandora also write computer programs like us. Their programs only consist of capital letters (‘A’ to ‘Z’) which they learned from the Earth. On 
planet Pandora, hackers make computer virus, so they also have anti-virus software. Of course they learned virus scanning algorithm from the Earth. Every virus has a pattern string which consists of only capital letters. If a virus’s pattern string is a substring of a program, or the pattern string is a substring of the reverse of that program, they can say the program is infected by that virus. Give you a program and a list of virus pattern strings, please write a program to figure out how many viruses the program is infected by.
 

Input
There are multiple test cases. The first line in the input is an integer T ( T<= 10) indicating the number of test cases.

For each test case:

The first line is a integer n( 0 < n <= 250) indicating the number of virus pattern strings.

Then n lines follows, each represents a virus pattern string. Every pattern string stands for a virus. It’s guaranteed that those n pattern strings are all different so there 
are n different viruses. The length of pattern string is no more than 1,000 and a pattern string at least consists of one letter.

The last line of a test case is the program. The program may be described in a compressed format. A compressed program consists of capital letters and 
“compressors”. A “compressor” is in the following format:

[qx]

q is a number( 0 < q <= 5,000,000)and x is a capital letter. It means q consecutive letter xs in the original uncompressed program. For example, [6K] means 
‘KKKKKK’ in the original program. So, if a compressed program is like:

AB[2D]E[7K]G

It actually is ABDDEKKKKKKKG after decompressed to original format.

The length of the program is at least 1 and at most 5,100,000, no matter in the compressed format or after it is decompressed to original format.
 

Output
For each test case, print an integer K in a line meaning that the program is infected by K viruses.
 

Sample Input
32ABDCBDACB3ABCCDEGHIABCCDEFIHG4ABBACDEEBBBFEEEA[2B]CD[4E]F
 

Sample Output
032
Hint
In the second case in the sample input, the reverse of the program is ‘GHIFEDCCBA’, and ‘GHI’ is a substring of the reverse, so the program is infected by virus ‘GHI’.
 


题目大意:给出一些字符串和一个总串,如果前面字符串或者其反串出现在总串中就称这个串在总串中,问一共在总串中出现了几个前面的小字符串。

题目分析:AC自动机入门题,需要注意的是输入格式,如A[2B]CD[4E]F就代表ABBCDEEEEF,还有如果同时出现了一个字符串的正串和反串只能算一个,但如果上文字符串中同时出现这个串的正串和反串就得算2个,,,你们自己感受下。

其实说的玄乎乎的都是忽悠人的,匹配时把总串正反分别匹配一次,然后如果遇到单词就+1,然后把串尾的标记抹除掉然后就跟2222没啥区别了。

////  main.cpp//  HDU3695////  Created by teddywang on 16/4/7.//  Copyright © 2016年 teddywang. All rights reserved.//#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef struct node{    int num;    int flag;    node *next[26];    node *fail;}trienode;char s[6100009],str[6100009];trienode *qu[6100000];int ptr,ans,head,num,tail;char dir[2005];trienode *root;trienode *creat_node(){    trienode *r=new node;    r->flag=r->num=0;    for(int i=0;i<26;i++)        r->next[i]=NULL;    r->fail=NULL;    return r;}void init(){    ptr=ans=num=0;    head=tail=0;    root=creat_node();}void insert_node(char *s){    trienode *h,*r=root;    int len=strlen(s);    for(int i=0;i<len;i++)    {        int buf=s[i]-'A';        if(r->next[buf]==NULL)        {            h=creat_node();            r->next[buf]=h;            r=h;        }        else r=r->next[buf];    }    r->flag=1;    r->num=1;}void build_ac(){    qu[head++]=root;    while(tail<head)    {        trienode *p=qu[tail++];        for(int i=0;i<26;i++)        {            if(p->next[i]!=NULL)            {                if(p==root)                    p->next[i]->fail=root;                else                {                    trienode *temp=p->fail;                    while(temp!=NULL)                    {                        if(p->next[i]!=NULL)                        {                            p->next[i]->fail=temp->next[i];                            break;                        }                        temp=temp->fail;                    }                    if(temp==NULL) p->next[i]->fail=root;                }                qu[head++]=p->next[i];            }            else            {                if(p==root)                    p->next[i]=root;                else p->next[i]=p->fail->next[i];            }        }    }}int query(char *s){    trienode *p=root;    int num=0;    int len=strlen(s);    for(int i=0;i<len;i++)    {        int buf=s[i]-'A';        while(p->next[buf]==NULL&&p!=root)            p=p->fail;        p=p->next[buf];            trienode *temp=p;            while(temp!=root)            {                if(temp->flag==1)                {                    num+=temp->num;                    temp->flag=0;                    temp->num=0;                }                else break;                temp=temp->fail;            }    }    return num;}int main(){    int n;    cin>>n;    while(n--)    {        init();        cin>>num;        while(num--)        {            scanf("%s",dir);            insert_node(dir);        }        build_ac();        scanf("%s",s);        int len=strlen(s);        int l=0,i=0;        while(i<len)        {            if(s[i]!='[') str[l++]=s[i++];            else            {                int m=0;                char alpha = '\0';                while(s[++i]!=']')                {                    if(s[i]<='9'&&s[i]>='0')                    {                        m=m*10+s[i]-'0';                    }                    else alpha=s[i];                }                for(int j=0;j<m;j++)                    str[l++]=alpha;                i++;            }        }        len=l;        for(int i=0;i<len;i++)            s[i]=str[len-1-i];        s[len]='\0';str[len]='\0';        ans+=query(str);        ans+=query(s);        cout<<ans<<endl;    }}

PS:这次换了个模板,相对上一个而言这个还是好理解和记忆一些。

0 0