二维hash问题
去两个模,然后类似前缀和的思想,去计算(i,j) -> (a,b)这个矩形的hash值
然后注意多用unsigned int 自然溢出!
记几个适合hash的质数吧:211 1e6+3 1e9+7
但是对于这道题而言,第一个base用2就足以
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1005;
const int mod=99999971;
int n,m,a,b;
int base1=2,base2=9804799;
bool ma[mod+2];
unsigned int G[1005][1005],sum[maxn][maxn],has[1005][1005],pow1[maxn],pow2[maxn];
int main()
{
freopen("juzhen.in","r",stdin);
freopen("juzhen.out","w",stdout);
scanf("%d%d%d%d",&n,&m,&a,&b);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%1d",&sum[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
sum[i][j]+=sum[i-1][j]*base1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
sum[i][j]+=sum[i][j-1]*base2;
pow1[0]=1; pow2[0]=1;
for(int i=1;i<=1000;i++) pow1[i]=pow1[i-1]*base1,pow2[i]=pow2[i-1]*base2;
for(int i=a;i<=n;i++)
for(int j=b;j<=m;j++)
{
unsigned int x=sum[i][j];
x-=sum[i-a][j]*pow1[a];
x-=sum[i][j-b]*pow2[b];
x+=sum[i-a][j-b]*pow2[b]*pow1[a];
x%=mod;
ma[x]=1;
}
int q;
scanf("%d",&q);
while(q--)
{
for(int i=1;i<=a;i++)
for(int j=1;j<=b;j++)
scanf("%1d",&G[i][j]);
for(int i=1;i<=a;i++)
for(int j=1;j<=b;j++)
G[i][j]+=G[i-1][j]*base1;
for(int i=1;i<=a;i++)
for(int j=1;j<=b;j++)
G[i][j]+=G[i][j-1]*base2;
printf("%d\n",ma[G[a][b]%mod]?1:0);
}
return 0;
}