Matrix 黑暗爆炸 - 2351
原题链接
考察:hash
思路:
二维hash模板题,先横着做一遍hash,再纵着坐一遍前缀和hash.获得\(a,b\)矩阵的hash值参考了前缀和公式:
\(sum[i,j] - sum[i,b]*p1[j-b]-sum[a,j]*p2[i-a]+sum[a,b]*p1[j-b]*p2[i-a]\)
Code
#include <iostream>
#include <cstring>
#include <set>
using namespace std;
typedef unsigned long long ULL;
const int N = 1010,P1 = 131,P2 = 13331,S = 110;
ULL x[N],y[N],p[2][N],s[N][N],temp[S][S];
char mp[N][N];
set<ULL> has;
int n,m,a,b,Q;
ULL query(int l,int r,int i,int j)
{
return s[i][j]-s[l][j]*p[0][i-l]-s[i][r]*p[1][j-r]+s[l][r]*p[0][i-l]*p[1][j-r];
}
void init()
{
p[0][0] = p[1][0] = 1;
for(int i=1;i<=m;i++)
p[0][i] = p[0][i-1]*P1;
for(int i=1;i<=n;i++)
p[1][i] = p[1][i-1]*P2;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
s[i][j] += s[i][j-1]*P2+mp[i][j];
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
{
s[i][j] += s[i-1][j]*P1;
if(i>=a&&j>=b)
{
ULL x = query(i-a,j-b,i,j);
has.insert(x);
}
}
}
int main()
{
scanf("%d%d%d%d",&m,&n,&a,&b);
for(int i=1;i<=m;i++)
scanf("%s",mp[i]+1);
init();
scanf("%d",&Q);
while(Q--)
{
for(int i=1;i<=a;i++) scanf("%s",mp[i]+1);
ULL tmp[S];
for(int i=1;i<=a;i++)
{
tmp[i] = 0;
for(int j=1;j<=b;j++)
tmp[i] = tmp[i]*P2+mp[i][j];
}
ULL sum = 0;
for(int i=1;i<=a;i++) sum = sum*P1+tmp[i];
if(has.count(sum)) puts("1");
else puts("0");
}
return 0;
}