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\n", solve(aim));
    }
    return 0;
}

 

posted @ 2018-08-23 19:48  KirinSB  阅读(356)  评论(0编辑  收藏  举报