zoukankan      html  css  js  c++  java
  • 156. 矩阵[二维的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<?XML:NAMESPACE PREFIX = "[default] http://www.w3.org/1998/Math/MathML" NS = "http://www.w3.org/1998/Math/MathML" />A≤100,M,N,B≤1000M,N,B≤1000,Q≤1000Q≤1000

    输入样例:
    3 3 2 2
    111
    000
    111
    3
    11
    00
    11
    11
    00
    11
    
    输出样例:
    1
    0
    1

    首先,此题是一维hash的拓展。
    我们可以通过先将每一行hash完成,然后通过枚举a,b大小的矩阵,计算hash值,通过公式推导,
    a列到a+1列的公式是,s = s*p^b + get(h[j], l, r);也就是该行的hash值。
    最后给出代码:
    #include <iostream>
    #include <algorithm>
    #include <unordered_set>
    using namespace std;
    
    using ULL = unsigned long long;
    const int N = 1010, M = N*N, base = 131;
    char str[N];
    ULL h[N][N], p[M];
    int n, m, a, b;
    ULL get(ULL h[], int l, int r){
        return h[r] - h[l - 1] * p[r - l + 1];
    }
    
    int main() {
        cin >> n >> m >> a >> b;
        p[0] = 1;
        for(int i = 1; i <= n*m; ++ i) p[i] = p[i-1] * base;//对应的进制数的幂
        for(int i = 1; i <= n; ++ i) {//处理行并hash
            cin >> (str+1);
            for(int j = 1; j <= m; ++ j)h[i][j] = h[i][j - 1] * base + str[j] - '0';
        }
        unordered_set<ULL> S;
        for(int i = b; i <= m; ++ i) {//处理每个矩形hash值。
            ULL s = 0;
            int l = i - b + 1, r = i;
            for(int j = 1; j <= n; ++ j){
                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) S.insert(s);
            }
        }
    
        int k;
        cin >> k;
        while(k --) {
            ULL s = 0;
            for(int i = 1; i <= a; ++ i) {//处理输入要查找的矩形,计算hash值
                cin >> (str+1);
                for(int j = 1; j <= b; ++ j) s = s*base + str[i] - '0';
            }
            if(S.count(s))puts("1");//看是否在集合中
            else puts("0");
        }
        return 0;
    }
  • 相关阅读:
    Golang网络编程-套接字(socket)篇
    Golang并发编程-传统的同步工具"锁"实战篇
    Golang并发编程-select实战篇
    Golang并发编程-channel实战篇
    Golang并发编程-Go程(Goroutine)实战篇
    Jenkins实现简单流程部署代码
    Jenkins权限管理
    Jenkins插件管理篇
    Jenkins部署实战案例
    Golang常见的字符串函数操作实战篇
  • 原文地址:https://www.cnblogs.com/rstz/p/13385539.html
Copyright © 2011-2022 走看看