3 AA BB CC ooxxCC%dAAAoen....END
AA: 2 CC: 1HintHit: 题目描述中没有被提及的所有情况都应该进行考虑。比如两个病毒特征码可能有相互包含或者有重叠的特征码段。 计数策略也可一定程度上从Sample中推测。
本题时要统计母串中模式串出现的次数。在tries的基础上建立前缀指针,从而形成tries图,ac自动机就建立起来了。建议事先写好ac自动机的模板,然后在模板基础上做些改动即可解本题。
#include <iostream> #include<algorithm> using namespace std; const int kind = 26; struct node { node *fail; //失败指针 node *next[kind]; //Tire每个节点的26个子节点(最多26个字母) int count; //是否为该单词的最后一个节点 node() { //构造函数初始化 fail=NULL; count=0; memset(next,NULL,sizeof(next)); } }*q[50*1000+10]; //队列,方便用于bfs构造失败指针,大小应依据Tries图节点个数而定 char keyword[1000+5][50+5]; //输入的单词 char str[2000010]; //模式串 int num[1000+10]; int head,tail; //队列的头尾指针 void insert(char *str,node *root,int ind) //建立一颗以root为根节点的不带前缀指针的字典树 { node *p=root; int i=0,index; while(str[i]) { index=str[i]-'A'; if(p->next[index]==NULL) p->next[index]=new node(); p=p->next[index]; i++; } p->count=ind; } void build_ac_automation(node *root) //在建好的字典树上添加前缀指针,形成Tries图,即ac自动机 { int i; root->fail=NULL; q[head++]=root; while(head!=tail) { node *temp=q[tail++]; node *p=NULL; for(i=0;i<26;i++) { if(temp->next[i]!=NULL) { if(temp==root) temp->next[i]->fail=root; else { p=temp->fail; while(p!=NULL) { if(p->next[i]!=NULL) { temp->next[i]->fail=p->next[i]; break; } p=p->fail; } if(p==NULL) temp->next[i]->fail=root; } q[head++]=temp->next[i]; } } } } int query(node *root,int ind) //有多少种模式串出现在母串str[]中 { int i=0,cnt=0,index,len=strlen(str),j; node *p=root; while(str[i]) { if(str[i]>='A'&&str[i]<='Z') { index=str[i]-'A'; // cout<<index<<endl; while(p->next[index]==NULL && p!=root) p=p->fail; p=p->next[index]; p=(p==NULL)?root:p; node *temp=p; while(temp!=root&&temp->count) { num[temp->count]++; temp=temp->fail; } } else p=root; i++; } return cnt; } int main() { int n,t,i,m,j,tag; while(~scanf("%d",&n)) { head=tail=0; node *root=new node(); getchar(); for(i=1;i<=n;i++) { gets(keyword[i]); insert(keyword[i],root,i); } build_ac_automation(root); memset(num,0,sizeof(num)); gets(str); // cout<<str<<endl; query(root,i); for(i=1;i<=n;i++) { if(num[i]) printf("%s: %d\n",keyword[i],num[i]); } } return 0; }