思路(主要参考:传送门)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/4e237ecff9ea95b7d36f2c360660f2ab.png)
代码
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<set>
#define ull unsigned long long
using namespace std;
int N,M,T,P,Q;
char f[1000][1000];
char p[1000][1000];
ull Hash[1000][1000],t[1000][1000];
void compute_hash(char a[1000][1000],int n,int m)
{
const ull B1=1e9+7;
const ull B2=1e9+9;
ull t1=1;
for(int i=0;i<Q;i++) t1*=B1;
for(int i=0;i<n;i++)
{
ull e=0;
for(int j=0;j<Q;j++) e=e*B1+a[i][j];
for(int j=0;j+Q<=m;j++)
{
t[i][j]=e;
if(j+Q<m) e=e*B1+a[i][j+Q]-a[i][j]*t1;
}
}
ull t2=1;
for(int i=0;i<P;i++) t2*=B2;
for(int j=0;j+Q<=m;j++)
{
ull e=0;
for(int i=0;i<P;i++) e=e*B2+t[i][j];
for(int i=0;i+P<=n;i++)
{
Hash[i][j]=e;
if(i+P<n) e=e*B2+t[i+P][j]-t[i][j]*t2;
}
}
}
int main()
{
multiset<ull> s;
int count=0;
while(cin>>N>>M>>T>>P>>Q)
{
s.clear();
if(N==M&&N==T&&N==T&&N==P&&N==Q) break;
for(int i=0;i<N;i++)
cin>>f[i];
for(int t=1;t<=T;t++)
{
for(int i=0;i<P;i++)
cin>>p[i];
compute_hash(p,P,Q);
s.insert(Hash[0][0]);
}
compute_hash(f,N,M);
for(int i=0;i+P<=N;i++)
for(int j=0;j+Q<=M;j++)
s.erase(Hash[i][j]);
int ans=T-s.size();
cout<<"Case "<<++count<<": "<<ans<<endl;
}
}