二维hash
用于一般解决字符串矩阵问题,我们可以定义两个 进制数,求出
m*n
字符串矩阵映射的数
求大小位 r*c的子矩阵,可以由推得 :
ans[i][j]=hash[i][j]-hash[i][j-r]*p1[r]+hash[i-c][j]*p2[c]]+hash[i-1][j-1]*p1[r]*p2[c];
矩阵模板
题解:
我们先求出整体矩阵的hash[ ][ ]: 在根据上面公式求得当前给的大小的数组对应的所有hash值,然后用二分查找,或者桶数组的方式去存放,当然对于铜数组一定要取模,最好%一个素数。
注意: ios::sync_with_stdio(false); 用这个的时候不能和scanf()一起用,会wa。
AC 代码 二分:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+5;
#define ull unsigned long long
ull ha[maxn][maxn],pow1[maxn],pow2[maxn];
const ull base1=2;
const ull base2=9191891;
char s[maxn][maxn];
char str[maxn][maxn];
ull h[maxn][maxn];
ull mp[2000000];
int main()
{
// ios::sync_with_stdio(false);
// cin.tie(0);
ull n,m,l,r,cnt=0;
cin>>n>>m>>l>>r;
for(ull i=1; i<=n; i++)
scanf("%s",s[i]+1);
pow1[0]=pow2[0]=1;
for(ull i=1; i<=1000; i++)
pow1[i]=pow1[i-1]*base1,pow2[i]=pow2[i-1]*base2;
for(ull i=1; i<=n; i++)
for(ull j=1; j<=m; j++)
ha[i][j]=ha[i][j-1]*base1+s[i][j]-'0';
for(ull i=1; i<=n; i++)
for(ull j=1; j<=m; j++)
ha[i][j]=ha[i][j]+ha[i-1][j]*base2;
for(ull i=l; i<=n; i++)
for(ull j=r; j<=m; j++){
mp[++cnt]=ha[i][j]-ha[i][j-r]*pow1[r]-ha[i-l][j]*pow2[l]+ha[i-l][j-r]*pow1[r]*pow2[l];
}
sort(mp+1,mp+cnt+1);
int q;
scanf("%d",&q);
memset(str,0,sizeof(0));
while(q--)
{
for(ull i=1;i<=l;i++)
scanf("%s",str[i]+1);
for(ull i=1;i<=l;i++)
for(ull j=1;j<=r;j++)
h[i][j]=h[i][j-1]*base1+str[i][j]-'0';
for(ull i=1;i<=l;i++)
for(ull j=1;j<=r;j++)
h[i][j]=h[i][j]+h[i-1][j]*base2;
ull x=lower_bound(mp+1,mp+cnt+1,h[l][r])-mp;
if(mp[x]==h[l][r])
printf("1\n");
else
printf("0\n");
}
}
AC 代码 桶数组:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+5;
#define ull unsigned long long
ull ha[maxn][maxn],pow1[maxn],pow2[maxn];
const ull base1=131;
const ull base2=13331;
char s[maxn][maxn];
char str[maxn][maxn];
ull h[maxn][maxn];
ull mp[2000000];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
ull n,m,l,r,cnt=0;
cin>>n>>m>>l>>r;
for(ull i=1; i<=n; i++)
cin>>s[i]+1;
pow1[0]=pow2[0]=1;
for(ull i=1; i<=1000; i++)
pow1[i]=pow1[i-1]*base1,pow2[i]=pow2[i-1]*base2;
for(ull i=1; i<=n; i++)
for(ull j=1; j<=m; j++)
ha[i][j]=ha[i][j-1]*base1+s[i][j]-'0';
for(ull i=1; i<=n; i++)
for(ull j=1; j<=m; j++)
ha[i][j]=ha[i][j]+ha[i-1][j]*base2;
ull ans;
for(ull i=l; i<=n; i++)
for(ull j=r; j<=m; j++){
ans=ha[i][j]-ha[i][j-r]*pow1[r]-ha[i-l][j]*pow2[l]+ha[i-l][j-r]*pow1[r]*pow2[l];
mp[ans%100007]=1;
}
sort(mp+1,mp+cnt+1);
int q;
cin>>q;
while(q--)
{
for(ull i=1;i<=l;i++)
cin>>str[i]+1;
for(ull i=1;i<=l;i++)
for(ull j=1;j<=r;j++)
h[i][j]=h[i][j-1]*base1+str[i][j]-'0';
for(ull i=1;i<=l;i++)
for(ull j=1;j<=r;j++)
h[i][j]=h[i][j]+h[i-1][j]*base2;
if(mp[h[l][r]%100007])
cout<<1<<endl;
else
cout<<0<<endl;
}
}