Given anNMmatrix, your task is to nd the number of occurences of anXYpattern.
Input
The rst line contains a single integert(t15), the number of test cases.
For each case, the rst line contains two integersNandM(N;M1000). The nextNlinescontainMcharacters each.
The next line contains two integersXandY(X;Y100). The nextXlines containYcharacterseach.
Output
For each case, output a single integer in its own line, the number of occurrences.
Sample Input
2
1 1
x
1 1
y
3 3
abc
bcd
cde
2 2
bccd
Sample Output
0
2
http://fastvj.rainng.com/problem/UVA-11019
题目大意:给出一个大的二维字符矩阵T,一个小的二维矩阵P,问P在T中存在的次数。
解题思路:思路很简单,使用一个二维矩阵cnt,如果cnt[r][c]表示T中以(r,c)为左上角、与P等大的矩形有多少个完整的行和P对应位置的行完全相同。当P的第j行出现在T的第r行、起始列号为i时,意味着cnt[r-j+1][i-y+2]++,其中具体加几和存储的起始位置有关,按照自己的规则即可。所有匹配结束后,那些cnt[r][c] == x(P的行数)的点就是一个二维匹配点。另外需要注意的是P中可能存在重复,存在重复的模板会导致字典树中结点编号覆盖,所以使用一个vector数组保存所有的编号。
/*
@Author: Top_Spirit
@Language: C++
*/
#include
using namespace std ;
typedef unsigned long long ull ;
typedef long long ll ;
typedef pair < int, int > P ;
const int Maxn = 1e5 + 10 ;
const int INF = 0x3f3f3f3f ;
const double PI = acos(-1.0) ;
const ull seed = 133 ;
const int _Max = 1000 + 10 ;
int Next[Maxn][26], fail[Maxn], cnt[_Max][_Max], tot ;
vector < int > ve[Maxn] ;
string t[Maxn], p[Maxn] ;
void Insert(string s, int index){
int root = 0 ;
for (auto i : s){
int id = i - 'a' ;
if (!Next[root][id]) Next[root][id] = ++tot ;
root = Next[root][id] ;
}
ve[root].push_back(index);
}
void getFail (){
queue < int > que ;
for (int i = 0; i < 26; i++){
if (Next[0][i]){
fail[Next[0][i]] = 0 ;
que.push(Next[0][i]) ;
}
}
while (!que.empty()){
int tmp = que.front() ;
que.pop() ;
for (int i = 0; i < 26; i++){
if (Next[tmp][i]) {
fail[Next[tmp][i]] = Next[fail[tmp]][i] ;
que.push(Next[tmp][i]) ;
}
else Next[tmp][i] = Next[fail[tmp]][i] ;
}
}
}
void query(string s, int r, int y){
int root = 0, p = root ;
for (int i = 0; s[i]; i++){
int id = s[i] - 'a' ;
while (p && !Next[p][id]) p = fail[p] ;
if (!p) p = root ;
p = Next[p][id] ;
for (int k = 0; k < ve[p].size(); k++){
int j = ve[p][k] ;
if (r - j + 1 > 0) cnt[r - j + 1][i - y + 2]++ ;
}
}
}
int Count(int n, int m, int x){
int ans = 0 ;
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
if (cnt[i][j] == x) ans++ ;
}
}
return ans ;
}
int n, m, x, y ;
int main (){
int T ;
cin >> T ;
while (T--){
cin >> n >> m ;
tot = 0 ;
for (int i = 1; i <= n; i++) cin >> t[i] ;
memset(Next, 0, sizeof(Next)) ;
memset(cnt, 0, sizeof(cnt)) ;
memset(fail, 0, sizeof(fail)) ;
for (int i = 0; i < Maxn; i++) ve[i].clear() ;
cin >> x >> y ;
for (int i = 1; i <= x; i++) {
cin >> p[i] ;
Insert(p[i], i) ;
}
getFail() ;
for (int i = 1; i <= n; i++){
query(t[i], i, y) ;
}
cout << Count(n, m, x) << endl ; ;
}
return 0;
}