【二维哈希_匹配】UVa 11019 - Matrix Matcher

UVa 11019 - Matrix Matcher

题意:从n*m的字符矩阵中找到有多少个x*y的字符矩阵。


二维哈希

Hash[ ][ ]的更新

Hash[i][j] = Hash[i - 1][j] * base[0] + Hash[i][j - 1] * base[1] - Hash[i - 1][j - 1] * base[0] * base[1] + mp[i - 1][j - 1] - 'a' + 1;
//这里mp是从(0,0)开始

区间哈希Hash[lx, rx][ly, ry]的获取 

ull getHash(int lx, int ly, int rx, int ry)
{
    ull ans = Hash[rx][ry] - Hash[lx - 1][ry] * p[0][rx - lx + 1] - Hash[rx][ly - 1] * p[1][ry - ly + 1] + Hash[lx - 1][ly - 1] * p[0][rx - lx + 1] * p[1][ry - ly + 1];
    return ans;
}

最后,就是遍历一遍所有大小为x*y的矩阵和给定的矩阵哈希值相比较即可。 


AC CODE

 

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxN = 1003;
const ull base[2] = {19260817, 133331};
ull Hash[maxN][maxN];
ull p[2][maxN];
char nm[maxN][maxN];
char xy[maxN][maxN];

void pre()
{
    p[0][0] = p[1][0] = 1;
    for(int i = 1; i <= 1000; ++ i) p[0][i] = p[0][i - 1] * base[0], p[1][i] = p[1][i - 1] * base[1];
}

ull getHash(int lx, int ly, int rx, int ry)
{
    ull ans = Hash[rx][ry] - Hash[lx - 1][ry] * p[0][rx - lx + 1] - Hash[rx][ly - 1] * p[1][ry - ly + 1] + Hash[lx - 1][ly - 1] * p[0][rx - lx + 1] * p[1][ry - ly + 1];
    return ans;
}

int main()
{
    pre();
    int TAT; scanf("%d", &TAT);
    while(TAT -- )
    {
        int n, m; scanf("%d%d", &n, &m);
        for(int i = 0; i < n; ++ i)
            scanf("%s", nm[i]);
        int x, y; scanf("%d%d", &x, &y);
        for(int i = 0; i < x; ++ i )
            scanf("%s", xy[i]);

        Hash[0][0] = 0;
        for(int i = 1; i <= x; ++ i )
            for(int j = 1; j <= y; ++ j )
                Hash[i][j] = Hash[i - 1][j] * base[0] + Hash[i][j - 1] * base[1] - Hash[i - 1][j - 1] * base[0] * base[1] + xy[i - 1][j - 1] - 'a' + 1;
        ull tarHash = Hash[x][y];
        Hash[0][0] = 0;
        for(int i = 1; i <= n; ++ i )
            for(int j = 1; j <= m; ++ j )
                Hash[i][j] = Hash[i - 1][j] * base[0] + Hash[i][j - 1] * base[1] - Hash[i - 1][j - 1] * base[0] * base[1] + nm[i - 1][j - 1] - 'a' + 1;
        int ans = 0;
        for(int i = 1; i <= n - x + 1; ++ i )
        {
            for(int j = 1; j <= m - y + 1; ++ j )
            {
                if(tarHash == getHash(i, j, i + x - 1, j + y - 1))
                    ++ ans;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}
发布了242 篇原创文章 · 获赞 68 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_44049850/article/details/104201240