As long as each row of the template string into the AC automaton, and then match the row, each time the match succeeds, the line corresponding to the upper left corner of the character matrix counter +1, the last count of the number of counter matrix is the number of the upper left corner of the line can be.
The idea is very simple, but the idea is very good, but to note that there are two lines on the template is the same, inserted into the AC automaton will be plugged into the same node, in order to distinguish, I still carefully opened a vector, and then 1 a.
#include <bits/stdc++.h>#defineREP (I,A,B) for (int i=a;i<=b;i++)#defineMS0 (a) memset (A,0,sizeof (a))using namespaceStd;typedefLong Longll;Const intmaxn=12000;Const intinf=1e9+Ten;intn,m;intx, y;Chars[ -][ -],t[ -][ -];intcnt[ -][ -];structtrie{intch[maxn][ -]; //int ID[MAXN];///id[k] means kth rowvector<int>ID[MAXN]; intF[MAXN]; intLAST[MAXN]; intRt,tot; intNewNode () {++tot; memset (Ch[tot],-1,sizeof(Ch[tot])); //id[tot]=0;id[tot].clear (); returntot; } voidinit () {REP (I,0, maxn-1) id[i].clear (); Tot=-1; RT=NewNode (); } voidInsertChar*s,intID) {intLen=strlen (s), u=RT; REP (i,0, len-1){ intc=s[i]-'a'; if(ch[u][c]==-1) ch[u][c]=NewNode (); U=Ch[u][c]; } id[u].push_back (ID); } voidbuild () {Queue<int>Q; F[RT]=rt;last[rt]=RT; REP (c,0, -){ if(~ch[rt][c]) f[ch[rt][c]]=Rt,q.push (Ch[rt][c]); Elsech[rt][c]=RT; } while(!Q.empty ()) { intu=Q.front (); Q.pop (); REP (c,0, -){ if(~ch[u][c]) f[ch[u][c]]=Ch[f[u]][c],q.push (Ch[u][c]); Elsech[u][c]=Ch[f[u]][c]; if((int) id[f[u]].size ()) last[u]=F[u]; Elselast[u]=Last[f[u]]; } } } void Get(intUintRowintCol) { if(!u)return; ///row-id[u]+1,col-y+1 for(intI=0; I<id[u].size (); i++){ if(row-id[u][i]+1>0&&col-y+1>0) cnt[row-id[u][i]+1][col-y+1]++; } Get(Last[u],row,col); } voidFindChar*s,intID) {intLen=strlen (s), u=RT; REP (i,0, len-1){ intc=s[i]-'a'; U=Ch[u][c]; if((int) Id[u].size ())Get(u,id,i+1); Else if(Last[u])Get(last[u],id,i+1); } }}; Trie AC;intMain () {Freopen ("In.txt","R", stdin); intT;cin>>u; while(t--) {ac.init (); scanf ("%d%d",&n,&m); REP (i,1, N) scanf ("%s", s[i]+1); scanf ("%d%d",&x,&y); REP (i,1, x) scanf ("%s", t[i]+1), Ac.insert (t[i]+1, i); Ac.build (); MS0 (CNT); REP (i,1, N) ac.find (s[i]+1, i); intans=0; REP (i,1, n-x+1) REP (J,1, m-y+1)if(cnt[i][j]==x) ans++; cout<<ans<<Endl; } return 0;}/**33 3xxxxxxxxx2 2xxxx1 1x1 1y3 3abcbcdcde2 2BCCD*/
View Code
UVA 11019 Matrix Matcher Two-dimensional string matching AC automata