這算是很經典的多模式串多原串的題目了,匹配的複雜度是O(n)的,這樣,直接上自動機,注意判重另外開一個vis變數表示第turn躺是否訪問過此結點即可。
運用靜態分配記憶體,跑了156ms。
My Code:
#include <cstdio><br />#include <cstring><br />#include <cstdlib><br />#include <algorithm><br />using namespace std;<br />const int MAX=101100;<br />const int MAXK=128;<br />struct Node{<br /> Node* ne[MAXK];<br /> Node* fail;<br /> int cnt,vis;<br />}node[MAX],*root;<br />Node* que[MAX];<br />char s[11000];<br />int K,ans[5],top;<br />Node* New(){<br /> Node* ret=&node[K++];<br /> ret->fail=NULL;<br /> ret->cnt=0;<br /> ret->vis=0;<br /> for(int i=0;i<MAXK;i++){<br /> ret->ne[i]=NULL;<br /> }</p><p> return ret;<br />}<br />void init(){<br /> K=0;<br /> root=New();<br />}<br />void insert(char* s,int num){<br /> Node* ptr=root;<br /> char* p=s;<br /> int id;</p><p> while(*p){<br /> id=*(p++);<br /> if(ptr->ne[id]==NULL){<br /> ptr->ne[id]=New();<br /> }<br /> ptr=ptr->ne[id];<br /> }</p><p> ptr->cnt=num;<br />}<br />void bfs(){<br /> int b=0,f=0;<br /> Node* now;<br /> Node* ptr;</p><p> que[b++]=root;<br /> while(f!=b){<br /> now=que[f++];<br /> for(int i=0;i<MAXK;i++){<br /> if(now->ne[i]!=NULL){<br /> if(now==root){<br /> now->ne[i]->fail=root;<br /> }else{<br /> ptr=now->fail;<br /> while(ptr!=NULL){<br /> if(ptr->ne[i]!=NULL){<br /> now->ne[i]->fail=ptr->ne[i];<br /> break;<br /> }else{<br /> ptr=ptr->fail;<br /> }<br /> }<br /> if(ptr==NULL){<br /> now->ne[i]->fail=root;<br /> }<br /> }<br /> que[b++]=now->ne[i];<br /> }<br /> }<br /> }<br />}<br />void find(char* s,int turn){<br />bool vis[520]={0};<br /> Node* ptr=root;<br /> Node* next;<br /> char* p=s;<br /> int id;</p><p>vis[0]=true;<br />top=0;<br /> while(*p){<br /> id=*(p++);<br /> while(ptr->ne[id]==NULL&&ptr!=root){<br /> ptr=ptr->fail;<br /> }<br /> ptr=ptr->ne[id];<br /> if(ptr==NULL){<br /> ptr=root;<br /> }<br /> next=ptr;<br /> while(next!=NULL&&next->vis!=turn){<br />if(!vis[next->cnt]){<br />ans[top++]=next->cnt;<br />vis[next->cnt]=true;<br />}<br />next->vis=turn;<br /> next=next->fail;<br /> }<br /> }<br />}<br />int main(){<br /> int n,tol;</p><p>while(~scanf("%d",&n)){<br />init();<br />gets(s);<br />for(int i=1;i<=n;i++){<br />gets(s);<br />insert(s,i);<br />}<br />bfs();<br />scanf("%d",&n);<br />tol=0;<br />gets(s);<br />for(int i=1;i<=n;i++){<br />gets(s);<br />find(s,i);<br />if(top){<br />printf("web %d:",i);<br />sort(ans,ans+top);<br />for(int j=0;j<top;j++){<br />printf(" %d",ans[j]);<br />}<br />puts("");<br />tol++;<br />}<br />}<br />printf("total: %d/n",tol);<br />}</p><p> return 0;<br />}<br />