预处理出原矩阵所有PxQ的矩阵hash值,再处理出小矩阵的hash值并存在一个set中,再把其中所有已经存在的hash值删去即可。
输入顺序是N,M,T,P,Q...千万别看错了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <queue>
#include <stack>
#include <utility>
#include <map>
#define pb push_back
#define mp make_pair
#define N 1055
#define M 20005
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
int n , m , X , Y , T , ca;
char s[N][N];
ULL h[N][N] , p[N][N] , power;
int pre[999983] , mcnt;
struct node
{
ULL x;
int next;
}e[1000000];
void work()
{
printf("Case %d: " , ++ ca);
int i , j , sum;
ULL x , y;
for (i = 1 ; i <= n ; ++ i)
scanf("%s" , s[i] + 1);
for (i = 1 ; i <= n ; ++ i)
for (j = 1 ; j <= m ; ++ j)
s[i][j] = (s[i][j] == '*') + 1;
power = 1 , sum = 0;
for (i = 1 ; i <= Y ; ++ i)
power *= 3;
for (i = 1 ; i <= n ; ++ i)
{
for (j = 1 ; j <= m ; ++ j)
h[i][j] = h[i][j - 1] * 3 + s[i][j];
for (j = 1 ; j + Y - 1 <= m ; ++ j)
p[i][j] = h[i][j + Y - 1] - power * h[i][j - 1];
}
power = 1;
for (i = 1 ; i <= X ; ++ i)
power *= 9973;
memset(pre , -1 , sizeof(pre));
mcnt = 0;
for (j = 1 ; j + Y - 1 <= m ; ++ j)
{
for (i = 1 ; i <= n ; ++ i)
h[i][j] = h[i - 1][j] * 9973 + p[i][j];
for (i = 1 ; i + X - 1 <= n ; ++ i)
{
x = h[i + X - 1][j] - power * h[i - 1][j];
y = x % 999983;
e[mcnt] = (node){x , pre[y]} , pre[y] = mcnt ++;
}
}
int ans = 0;
while (T --)
{
for (i = 1 ; i <= X ; ++ i)
scanf("%s" , s[i] + 1);
for (i = 1 ; i <= X ; ++ i)
for (j = 1 ; j <= Y ; ++ j)
s[i][j] = (s[i][j] == '*') + 1;
x = 0;
for (i = 1 ; i <= X ; ++ i)
{
y = 0;
for (j = 1 ; j <= Y ; ++ j)
y = y * 3 + s[i][j];
x = x * 9973 + y;
}
y = x % 999983;
for (i = pre[y] ; ~i ; i = e[i].next)
if (x == e[i].x)
{
++ ans;
break;
}
}
printf("%d\n" , ans);
}
int main()
{
while(scanf("%d%d%d%d%d" , &n,&m,&T,&X,&Y) , n)
work();
return 0;
}