二维矩阵hash

给定一个M行N列的01矩阵(只包含数字0或1的矩阵),再执行Q次询问,每次询问给出一个A行B列的01矩阵,求该矩阵是否在原矩阵中出现过。
输入格式
第一行四个整数M,N,A,B。
接下来一个M行N列的01矩阵,数字之间没有空格。
接下来一个整数Q。
接下来Q个A行B列的01矩阵,数字之间没有空格。
输出格式
对于每个询问,输出1表示出现过,0表示没有出现过。

数据范围
A≤100,M,N,B≤1000,Q≤1000
输入样例:
3 3 2 2
111
000
111
3
11
00
11
11
00
11
输出样例:
1
0
1

#include <bits/stdc++.h>
using namespace std ;
typedef unsigned long long ll ;
const int N = 1010 ;
ll h[N][N] , p[N * N] ;
const int base = 131 ;
ll get(ll f[] , ll l , ll r)
{
    return f[r] - f[l - 1] * p[r - l + 1] ;
}
int main()
{
    p[0] = 1 ;
    for(int i = 1 ; i < N * N ;i ++) p[i] = p[i - 1] * base ;
    int n , m , a , b ;
    char str[N] ;
    cin >> n >> m >> a >> b ;
    for(int i = 1; i <= n ;i ++) 
     {
         scanf("%s" , str + 1) ;
         for(int j = 1 ;j <= m ;j ++) 
          h[i][j] = h[i][j - 1] * base + str[j] - '0' ;
     }
    unordered_map<ll , int> mp ;
    for(int i = b ; i <= m ;i ++) 
     {
         ll s = 0 ;
         for(int j = 1 ; j <= n ;j ++) 
          {
              int l = i - b + 1 , r = i ;
              s = s * p[b] + get(h[j] , l , r) ;
              if(j > a) s -= get(h[j - a] , l , r) * p[a * b] ;
              if(j >= a) mp[s] = 1 ;
          }
     }
     int Q ;
     cin >> Q ;
     while(Q --) 
      {
          ll s = 0 ;
          for(int i = 1 ;i <= a ;i ++) 
           {
               scanf("%s" , str + 1) ;
               for(int j = 1; j <= b ;j ++) 
                s = s * base + str[j] - '0' ;
           }
          if(mp[s]) cout << "1" << endl ;
          else cout << "0"  << endl ;
      }
    return 0 ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值