• UVA 11019 Matrix Matcher(二维hash + 尺取)题解


    题意:在n*m方格中找有几个x*y矩阵。

    思路:二维hash,总体思路和一维差不太多,先把每行hash,变成一维的数组,再对这个一维数组hash变成二维hash。之前还在想怎么快速把一个矩阵的hash算出来,然后看到是尺取,也不知道是什么...这应该算是用到了这个思想吧。

    要先预处理每行y个的hash(看代码),然后每次算出上面两顶点在第一行的hash值,慢慢往下移。hash看上去就像是在算一个seed位数一样,seed取13那么就是把字符串转化为了一个13位数,这样想可能在移动的时候更容易理解代码的含义。

    代码:

    #include<stack>
    #include<vector>
    #include<queue>
    #include<set>
    #include<cstring>
    #include<string>
    #include<sstream>
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #define ll long long
    #define ull unsigned long long
    using namespace std;
    const int maxn = 1000 + 10;
    const int seed1 = 131;
    const int seed2 = 13131;
    const int MOD = 100013;
    const int INF = 0x3f3f3f3f;
    char s[maxn][maxn],str[maxn];
    ull ha[maxn][maxn];
    int T;
    int n, m, x, y;
    int solve(ull aim){
        ull bit = 1;
        for(int i = 1; i <= y - 1; i++)
            bit = bit * seed1;
        for(int i = 1; i <= n; i++){    //预处理每一行的hash
            ull sum = 0;
            for(int j = 1; j <= y - 1; j++){
                sum = sum * seed1 + s[i][j];
            }
            for(int j = y; j <= m; j++){
                sum = sum * seed1 + s[i][j];
                ha[i][j - y + 1] = sum;
                sum -= bit * s[i][j - y + 1];
            }
        }
        int ans = 0;
        bit = 1;
        for(int i = 1; i <= x - 1; i++)
            bit = bit * seed2;
        for(int j = 1; j <= m - y + 1; j++){
            ull sum = 0;
            for(int i = 1; i <= x - 1; i++){
                sum = sum * seed2 + ha[i][j];
            }
            for(int i = x; i <= n; i++){
                sum = sum * seed2 + ha[i][j];
                if(sum == aim) ans++;
                sum -= bit * ha[i - x + 1][j];
            }
        }
        return ans;
    
    }
    int main(){
        scanf("%d", &T);
        while(T--){
            scanf("%d%d", &n, &m);
            for(int i = 1; i <= n; i++)
                scanf("%s", s[i] + 1);
            scanf("%d%d", &x, &y);
            ull temp, aim = 0;  //先对x*y二维hash
            for(int i = 1; i <= x; i++){
                scanf("%s", str + 1);
                temp = 0;
                for(int j = 1; j <= y; j++){
                    temp = temp * seed1 + str[j];
                }
                aim = aim * seed2 + temp;
            }
            printf("%d
    ", solve(aim));
        }
        return 0;
    }
  • 相关阅读:
    HDU5914
    HDU1087(dp)
    HDU1711(KMP)
    HDU1251(字典树)
    HDU3068(Manacher算法)
    POJ2187(旋转卡壳)
    HDU1392(凸包)
    CodeForces 722B
    CodeForces 722A
    CodeForces 721B
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9525867.html
Copyright © 2020-2023  润新知