题目传送门

  快速的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. (已解决)cocos2d-x 运行时xcode提示错误:"vtable for XXX", referenced from;

    vtable/引用和虚函数相关,今天在添加一个层的时候报了这个错误,很低级的错误,忘了实现虚函数了(谨记!!) 若如果实现了虚函数还依然如此的话,可能是创建的时候忘了钩上 -desktop 选项了,把 ...

  2. java-Unicode与中文的转换

    package utils; import org.apache.commons.lang3.StringUtils; public class UnicodeUtils { public stati ...

  3. PHP面向对象构造和析构函数

    一.构造函数 用来生成对象的函数 <?php class Ren{ public $name; public $sex;//性别是人一出生就知道的,可以用构造函数来定义 /*public fun ...

  4. 关于linux下firefox无法播放mp3文件

    起因是发现在线翻译的网站没法发音. F12调出console,发现是没法解码mp3文件. 尝试安装deadbeef包,发现安装之后推荐安装的软件列表中有个名为ffmpeg的包.安装上之后,重启fire ...

  5. QString和char*互转

    1. QString转为char * // QString转QByteArray QByteArray sr = strQ.toLocal8Bit(); int len = sr.length(); ...

  6. 32网络通信之Poll模型

    多路复用并发模型  -- poll #include<poll.h> int  poll(struct pollfd *fds,  unsigned int nfds, int timeo ...

  7. 更换tomcat运行日志目录

    1.在tomcat安装文件夹的bin目录下,修改catalina.sh,改变catalina.out的输出目录 CATALINA_OUT="$CATALINA_BASE"/logs ...

  8. 关于SqlCommand对象的2个方法:ExecuteNonQuery 方法和ExecuteScalar方法

    1.SqlCommand.ExecuteNonQuery 方法 对连接执行 Transact-SQL 语句并返回受影响的行数. 语法:public override int ExecuteNonQue ...

  9. python将一个列表的元素随机打乱

    java可以用Collections.shuffle(List)来实现,python怎么实现呢? python要利用random模块的shuffle方法 代码如下: import random x = ...

  10. Hive 中的复合数据结构简介以及一些函数的用法说明

    参见下面这篇博客: Hive 中的复合数据结构简介以及一些函数的用法说明