bzoj 2462 矩阵模板 (二维hash)

二维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;
      }
}
发布了254 篇原创文章 · 获赞 25 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/yangzijiangac/article/details/104559148