题目传送门

  快速的vjudge传送门

  快速的UVa传送门

题目大意

  给定两个矩阵S和T,问T在S中出现了多少次。

  不会AC自动机做法。

  考虑一维的字符串Hash怎么做。

  对于一个长度为$l$的字符串$s$,它的Hash值$hash(s) = \sum_{i = 1}^{l}x^{l - i}s_{i}$。

  对于二维的情况,我们就取两个基,$x, y$,对于一个$n\times m$的矩阵$A$的Hash值可以表示为

$hash(A) = \sum_{i = 1}^{n}\sum_{j = 1}^{m}x^{n - i}y^{m - j}a_{ij}$

  然后以记录$S$的左上角的左上角的所有子矩阵的hash值(这个可以$O(1)$转移)。询问一个子矩阵的hash值,就可以$O(1)$回答。

  接下来就很简单了。枚举每个位置判断是否匹配。

Code

 /**
* UVa
* Problem#11019
* Accepted
* Time: 50ms
*/
#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;
typedef bool boolean; const unsigned int hash1 = , hash2 = ;
const int N = , M = ; int p1[N], p2[N];
int m, n, x, y;
char S[N][N], T[M][M];
unsigned int hs[N][N]; inline void prepare() {
p1[] = , p2[] = ;
for (int i = ; i < N; i++)
p1[i] = p1[i - ] * hash1;
for (int i = ; i < N; i++)
p2[i] = p2[i - ] * hash2;
} inline void init() {
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++)
scanf("%s", S[i] + );
scanf("%d%d", &x, &y);
for (int i = ; i <= x; i++)
scanf("%s", T[i] + );
} inline void solve() {
for (int i = ; i <= n; i++)
for (int j = ; j <= m; j++) {
hs[i][j] = hs[i - ][j - ] * hash1 * hash2 + (hs[i - ][j] - hs[i - ][j - ] * hash2) * hash1 + (hs[i][j - ] - hs[i - ][j - ] * hash1) * hash2 + S[i][j];
} /* unsigned int s1 = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
s1 += S[i][j] * p1[n - i] * p2[m - j]; cerr << s1 << " " << (97u * 200379 * 211985 + 98u * 200379 + 98u * 211985 + 97) << " " << hs[2][2] << endl;*/ int rt = ;
unsigned int s = , c;
for (int i = ; i <= x; i++)
for (int j = ; j <= y; j++)
s += T[i][j] * p1[x - i] * p2[y - j];
// cerr << s << endl;
for (int i = x; i <= n; i++)
for (int j = y; j <= m; j++) {
c = hs[i][j] - hs[i - x][j - y] * p1[x] * p2[y] - (hs[i][j - y] - hs[i - x][j - y] * p1[x]) * p2[y] - (hs[i - x][j] - hs[i - x][j - y] * p2[y]) * p1[x];
if (s == c)
rt++;
}
printf("%d\n", rt);
} int kase;
int main() {
prepare();
scanf("%d", &kase);
while (kase--) {
init();
solve();
}
return ;
}

UVa 11019 Matrix Matcher - Hash的更多相关文章

  1. UVA - 11019 Matrix Matcher hash+KMP

    题目链接:传送门 题解: 枚举每一行,每一行当中连续的y个我们hash 出来 那么一行就是 m - y + 1个hash值,形成的一个新 矩阵 大小是 n*(m - y + 1), 我们要找到x*y这 ...

  2. UVA 11019 Matrix Matcher 矩阵匹配器 AC自动机 二维文本串查找二维模式串

    链接:https://vjudge.net/problem/UVA-11019lrjP218 matrix matcher #include<bits/stdc++.h> using na ...

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

    题意:在n*m方格中找有几个x*y矩阵. 思路:二维hash,总体思路和一维差不太多,先把每行hash,变成一维的数组,再对这个一维数组hash变成二维hash.之前还在想怎么快速把一个矩阵的hash ...

  4. UVA 11019 Matrix Matcher ( 二维字符串匹配, AC自动机 || 二维Hash )

    题目: 传送门 题意: 给你一个 n * m 的文本串 T, 再给你一个 r * c 的模式串 S: 问模式串 S 在文本串 T 中出现了多少次. 解: 法一: AC自动机 (正解) 670ms 把模 ...

  5. UVA 11019 Matrix Matcher(ac自动机)

    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  6. UVA - 11019 Matrix Matcher (二维字符串哈希)

    给你一个n*m的矩阵,和一个x*y的模式矩阵,求模式矩阵在原矩阵中的出现次数. 看上去是kmp在二维情况下的版本,但单纯的kmp已经无法做到了,所以考虑字符串哈希. 类比一维情况下的哈希算法,利用容斥 ...

  7. AC自动机(二维) UVA 11019 Matrix Matcher

    题目传送门 题意:训练指南P218 分析:一行一行的插入,一行一行的匹配,当匹配成功时将对应子矩阵的左上角位置cnt[r][c]++;然后统计 cnt[r][c] == x 的数量 #include ...

  8. uva 11019 Matrix Matcher

    题意:给出一个n*m的字符矩阵T,你的任务是找出给定的x*y的字符矩阵P在T中出现了多少次. 思路:要想整个矩阵匹配,至少各行都得匹配.所以先把P的每行看做一个模式串构造出AC自动机,然后在T中的各行 ...

  9. UVA 11019 Matrix Matcher(哈希)

    题意 给定一个 \(n\times m\) 的矩阵,在给定一个 \(x\times y\) 的小矩阵,求小矩阵在大矩阵中出现的次数. \(1 \leq n,m \leq 1000\) \(1\leq ...

随机推荐

  1. SSH--完全分布式主机设置【克隆过安装过Hadoop的主机后】

    ====准备完全分布式主机的ssh==== 2018-12-21 14:27:47 1.删除所有主机上.ssh下所有文件 2.在s250主机上生成密钥对 $>ssh-keygen -t rsa ...

  2. 原生js---ajax---get方法传数据

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. sqlserver备份还原数据库时报占用错误

    .做项目时遇到这种情形:原来的test_dev数据库,想复制出test_ft供测试用.此时备份test_dev出test_backup文件,想直接还原成test_ft时会报占用错误. 还原数据库:Th ...

  4. [Unit Test] Unit Test Brief Introduction

    Levels of Testing- Acceptance- Performance- Functional- Integration- Unit Why Unit Testing- Feedback ...

  5. Metasploit渗透技巧:后渗透Meterpreter代理

    Metasploit是一个免费的.可下载的渗透测试框架,通过它可以很容易地获取.开发并对计算机软件漏洞实施攻击测试.它本身附带数百个已知软件漏洞的专业级漏洞攻击测试工具. 当H.D. Moore在20 ...

  6. Python全栈-day11-函数3

    装饰器 1.开放封闭原则 通常情况下,软件一旦上线就应该遵循开放封闭原则,即对修改封闭.对扩展开放 扩展开放需遵循两个原则: 1)不修改源代码 2)不修改原函数的调用方式 2.装饰器 器指的是工具,装 ...

  7. php-fpm慢日志配置

    upstream timed out (110: Connection timed out) while reading response header from upstream Nginx报错日志 ...

  8. hdu5439 二分

    题意 初始给了 1 2 两个数 第二步 因为第2个数是2 所以  在序列后面放上2个2 包括他自己之前有的 序列变成 1 2 2 第三步 因为第3个数是2 所以  在序列后面放上2个3 就变成了 1 ...

  9. JDBC操作数据库步骤

    2018-11-04  20:23:24开始写 1.加载驱动程序(Class.forName) 2.建立连接获取数据库连接对象(DriverManager.getConnection) 3.向数据库发 ...

  10. 开源IOT平台

    用于IoT应用程序开发的10大开源软件: 1. DeviceHive DeviceHive基于AllJoyn的Data Art设备,同时也是AllSeen的联盟成员.这一款免费开源机器和机器通信(M2 ...