代码如下:
#include<cstdio> #include<cstring> #include<vector> #include<queue> #include<algorithm> using namespace std; const int MAX_NODE = 11111; const int SIGMA_SIZE = 26; char t[1111][1111],p[111][111]; int cc[1111][1111]; int ch[MAX_NODE][SIGMA_SIZE]; int fail[MAX_NODE]; int tot; vector <int> val[MAX_NODE]; struct Ac { void init() { memset(ch[0],0,sizeof(ch[0])); tot = 1; val[0].clear(); } int idx(char c) { return c - 'a'; } void insert(char *s,int len,int id) { int u = 0; for(int i = 0;i<len;i++) { int c = idx(s[i]); if(!ch[u][c]) { memset(ch[tot],0,sizeof(ch[tot])); val[tot].clear(); ch[u][c] = tot++; } u = ch[u][c]; } val[u].push_back(id); } void get_fail() { fail[0] = 0; queue <int> q; for(int i = 0;i<SIGMA_SIZE;i++) if(ch[0][i]) { fail[ch[0][i]] = 0; q.push(ch[0][i]); } while(!q.empty()) { int u = q.front(); q.pop(); for(int i = 0;i<SIGMA_SIZE;i++) { int v = ch[u][i]; if(!v) { ch[u][i] = ch[fail[u]][i]; continue; } q.push(v); int j = fail[u]; while(j && !ch[j][i]) j = fail[j]; j = ch[j][i]; fail[v] = j; } } } int find(int x,int y,int n,int m) { memset(cc,0,sizeof(cc)); int pre = 0; for(int i = 1;i<=n;i++) for(int j = 0;j<m;j++) { int c = idx(t[i][j]); pre = ch[pre][c]; for(int pos = 0;pos < val[pre].size();pos ++) { int ii = i - (val[pre][pos] - 1); int jj = j - (y - 1); cc[ii][jj]++; } } int ans = 0; for(int i = 1;i<=n;i++) for(int j = 0;j<m;j++) if(cc[i][j] == x) ans ++; return ans; } }ac; int main() { int _; scanf("%d",&_); while(_--) { ac.init(); int n,m; scanf("%d%d",&n,&m); for(int i = 1;i<=n;i++) scanf("%s",t[i]); int x,y; scanf("%d%d",&x,&y); for(int i = 1;i<=x;i++) { scanf("%s",p[i]); ac.insert(p[i],y,i); } ac.get_fail(); printf("%d\n",ac.find(x,y,n,m)); } return 0; }