注:long long 算数溢出相当于取模
一开始本来想偷懒,直接用map替代二分查找,然鹅他超内存了。。。
#include<bits/stdc++.h>
#define LL long long
using namespace std;
LL a[1005][1005];
LL b[1005][1005];
LL k=3;
LL p[1006];
LL ha[1005][1005];
LL M,N,A,B,Q,tot;
LL v[1000005];
char t;
LL now;
void check(LL x,LL y) {
LL ans=0;
for(LL i=x-A+1; i<=x; i++)//二维哈希计算方法
ans=ans*p[B]+(ha[i][y]-ha[i][y-B]*p[B]);
v[++now]=ans;//存储
}
bool cz(LL x)//二分查找
{
LL l=1,r=now,mid;
while(l<=r)
{
mid=(l+r)/2;
if(v[mid]<x)
l=mid+1;
else if(v[mid]==x)
return 1;
else
r=mid-1;
}
return 0;
}
int main() {
p[0]=1;
for(int i=1; i<=1000; i++)
p[i]=p[i-1]*k;//预处理k进制
cin>>M>>N>>A>>B;
for(int i=1; i<=M; i++)
for(int j=1; j<=N; j++) {//输入
scanf(" %c",&t);
a[i][j]=t-'0';
}
for(int i=1; i<=M; i++)
for(int j=1; j<=N; j++)//预处理大矩阵的哈希
ha[i][j]=ha[i][j-1]*k+a[i][j];
for(int i=A; i<=M; i++)
for(int j=B; j<=N; j++)//预处理每个小矩阵的哈希
check(i,j);
sort(v+1,v+now+1);//排序
cin>>Q;
while(Q--) {
tot=0;
for(int i=1; i<=A; i++)
for(int j=1; j<=B; j++) {
scanf(" %c",&t);
b[i][j]=t-'0';//输入
tot=tot*k+b[i][j];//计算小矩阵的哈希
}
printf("%d\n",cz(tot));
}
return 0;//再见毒瘤题
}
%%%%%
。。