這兩道題都是AC自動機的模板題。第二題比第一題只是要多了一個出現次數,這個很簡單,開個數組記錄就可以了。 但是第二題有坑點。一開始我我看了HINT以為要考慮兩個病毒互相包含的情況,就像這個樣例:
2AABABABAABBAABABA我以為應該輸出:
AABAB: 1ABA: 2然后怎么都不對。。。 后面拿別人的標程看看結果發現應該輸出:
AABAB: 1ABA: 1我說這個HINT不是害人嗎? 然后改完了交上去。。。繼續WA。。。 我不甘心地拿別人的標程和我自己的對拍,用的是我自己生成的隨機數據,拍了1000多組都沒錯。我就納悶了,結果后來看看別人的程序打的都是多組數據打法,就是一個while(scanf("%d",&n)!=EOF),然后我無語的想這題不會有多組數據吧?結果改成多組數據就AC了。我真的是無話可說。。。多組數據題目里也不講一下。。。
代碼:
//HDU2896病毒侵襲#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=505,maxm=100010;struct node{ int next[128],fail,flag;}T[maxm];int n,m,num=1,tot,que[maxm],head,tail;char ch[maxm];bool exist[maxn];void Insert(char *s,int x){ int p=1,len=strlen(s); for(int i=0;i<len;i++){ if(!T[p].next[s[i]])T[p].next[s[i]]=++num; p=T[p].next[s[i]]; } T[p].flag=x;}void Bfs(){ memset(que,head=tail=0,sizeof que); que[++tail]=1; while(head<tail){ int x=que[++head]; for(int i=0;i<128;i++){ if(T[x].next[i]){ int p=T[x].fail; while(!T[p].next[i])p=T[p].fail; T[T[x].next[i]].fail=T[p].next[i]; que[++tail]=T[x].next[i]; } } }}bool Find(char *s){ memset(exist,0,sizeof exist); int p=1,len=strlen(s);bool f=false; for(int i=0;i<len;i++){ while(p&&!T[p].next[s[i]])p=T[p].fail; p=T[p].next[s[i]]; int temp=p; while(temp&&T[temp].flag){ exist[T[temp].flag]=true; f=true; temp=T[temp].fail; } } return f;}int main(){ for(int i=0;i<128;i++){ T[0].next[i]=1; } scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("/n%s",ch); Insert(ch,i); } scanf("%d",&m);Bfs(); for(int i=1;i<=m;i++){ scanf("/n%s",ch); if(Find(ch)){ tot++;新聞熱點
疑難解答