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;
}