题目链接:HDU3695
3 2 AB DCB DACB 3 ABC CDE GHI ABCCDEFIHG 4 ABB ACDEE BBB FEEE A[2B]CD[4E]F
0 3 2HintIn 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; } }