题目链接
题意:问第二个矩阵中有几个第一个矩阵
hash,这次是二维,单独看每一维进行hash即可,暴力的时候还是使用技巧的暴力,类似滑动窗口的原理,枚举每一个宽度,然后向下滑动即可,有前缀和的意思。
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<set>
#include<map>
#include<string>
#include<cassert>
using namespace std;
#define cl(a,b) memset(a,b,sizeof(a))
#define fastIO ios::sync_with_stdio(false);cin.tie(0);
#define ll unsigned long long
#define pb push_back
#define gcd __gcd
#define For(i,j,k) for(int i=(j);i<=k;i++)
#define lowbit(i) (i&(-i))
#define _(x) printf("%d\n",x)
typedef vector<ll> vec;
typedef pair<int,int> PI;
const double EPS = 1e-8;
const int maxn = 2e3+100;
const int inf = 1 << 28;
int hp,wp,hm,wm;
ll p=43;//ull 会自动取模
ll pp[maxn*maxn],a[maxn][maxn];
char str[maxn];
int main(){
pp[0]=1ll;
for(int i=1;i<maxn*maxn;i++)pp[i]=pp[i-1]*p;//cout<<pp[i]<<endl;
while(~scanf("%d%d%d%d",&hp,&wp,&hm,&wm)){
cl(a,0);
ll t=0;
for(int i=1;i<=hp;i++){
scanf("%s",&str);
for(int j=0;j<wp;j++)t=t*p+(str[j]=='o'?0:1);
}
for(int i=1;i<=hm;i++){
scanf("%s",str+1);
for(int j=1;j<=wm;j++)a[i][j]=a[i][j-1]*p+(str[j]=='o'?0:1);
}
ll ans=0;
//printf("t = %llu\n",t);
for(int j=1;j+wp-1<=wm;j++){
ll tmp=0;
for(int i=1;i<=hp;i++){
tmp=tmp*pp[wp]+(a[i][j+wp-1]-a[i][j-1]*pp[wp]);
}
//printf("tmp = %llu\n",tmp);
if(tmp==t)ans++;
//滑动窗口,整体向下平移,添加头去掉尾部,类似尺取法思想
for(int i=2;i+hp-1<=hm;i++){
tmp-=(a[i-1][j+wp-1]-a[i-1][j-1]*pp[wp])*pp[hp*wp-wp];
tmp=tmp*pp[wp]+(a[i+hp-1][j+wp-1]-a[i+hp-1][j-1]*pp[wp]);
if(tmp==t)ans++;
}
}
printf("%llu\n",ans);
}
return 0;
}