UVA-11019

题意:

就是给你AB两个字符矩阵,问你B矩阵在A矩阵中的出现次数。

题解:  参考链接:https://blog.csdn.net/qq_38891827/java/article/details/80723483

我们可以进行二维hash,其实就是把n个横向串连在一起hash。
注意判相等的时候,我们不断进行尺取+hash,尺取的过程,我们删除当前第一行的hash值加上最后一行的hash值,删除第一行的hash值直接删去就可以
例如
AAAAAA
BBBBBB
CCCCCC
我们删去第一行的hash值 相当于把矩阵变成了
000000
BBBBBB
CCCCCC
此时我们再添加最后一行
000000
BBBBBB
CCCCCC
DDDDDD
如果这时候的B矩阵是
BBBBBB
CCCCCC
DDDDDD
这两个矩阵的hash值不同的,为了处理这种情况,我们把B矩阵相应的添加前几行
变成
000000
BBBBBB
CCCCCC
DDDDDD
这样再去匹配就可以了。
以上就是二维hash大概的处理方法(是我自己想的做法,如果有其他好的尺取方法欢迎指教
掌握了这个做法,我们就可以枚举矩阵的左上角,然后对于当前列数的矩阵从上向下进行尺取,hash判断就可以了。

代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<sstream>
#include<map>
using namespace std;
const int maxn=1e3+5;
const int N=1e6+5;
const int blo=31;
typedef unsigned long long ull;
ull hash_[maxn][maxn],xp[N];
char str[maxn][maxn],str2[maxn][maxn];
void init()
{
xp[0]=1;
for(int i=1; i<N; ++i)
{
xp[i]=xp[i-1]*blo;
}
}
ull Get_hash(int i,int j,int l)
{
return hash_[i][j]-hash_[i][j+l]*xp[l];
}
int main()
{
init();
int t;
scanf("%d",&t);
while(t--)
{
int n1,n2,m1,m2,ans=0;
scanf("%d%d",&n1,&m1);
for(int i=0; i<n1; ++i)
scanf("%s",str[i]);
scanf("%d%d",&n2,&m2);
for(int i=0; i<n2; ++i)
scanf("%s",str2[i]);
for(int i=0; i<n1; ++i)
{
hash_[i][m1]=0;
for(int j=m1-1; j>=0; j--)
{
hash_[i][j]=hash_[i][j+1]*blo+(str[i][j]-'A'+1);
}
}
ull tmp=0;
for(int i=n2-1; i>=0; --i)
{
for(int j=m2-1; j>=0; j--)
{
tmp=tmp*blo+(str2[i][j]-'A'+1);
}
}
for(int i=0; i<m1-m2+1; ++i)
{
ull tmp1=tmp,tmp2=0;
for(int j=n2-1; j>=0; j--)
{
tmp2=tmp2*xp[m2]+Get_hash(j,i,m2);
}
if(tmp1==tmp2) ans++;
for(int j=n2; j<n1; ++j)
{
tmp2-=Get_hash(j-n2,i,m2)*xp[(j-n2)*m2];
tmp2+=Get_hash(j,i,m2)*xp[j*m2];
tmp1=tmp1*xp[m2];
if(tmp2==tmp1) ans++;
} }
printf("%d\n",ans);
}
return 0;
}

UVA-11019 二维哈希算法的更多相关文章

  1. UVA 11019 二维匹配 AC自动机

    这个题目要求在一个大矩阵里面匹配一个小矩阵,是AC自动机的灵活应用 思路是逐行按普通AC自动机匹配,用过counts[i][j]记录一下T字符矩阵以i行j列为开头的与P等大的矩阵区域 有多少行已经匹配 ...

  2. 使用C语言实现二维,三维绘图算法(1)-透视投影

    使用C语言实现二维,三维绘图算法(1)-透视投影 ---- 引言---- 每次使用OpenGL或DirectX写三维程序的时候, 都有一种隔靴搔痒的感觉, 对于内部的三维算法的实现不甚了解. 其实想想 ...

  3. 使用C语言实现二维,三维绘图算法(3)-简单的二维分形

    使用C语言实现二维,三维绘图算法(3)-简单的二维分形 ---- 引言---- 每次使用OpenGL或DirectX写三维程序的时候, 都有一种隔靴搔痒的感觉, 对于内部的三维算法的实现不甚了解. 其 ...

  4. 使用C语言实现二维,三维绘图算法(2)-解析曲面的显示

    使用C语言实现二维,三维绘图算法(2)-解析曲面的显示 ---- 引言---- 每次使用OpenGL或DirectX写三维程序的时候, 都有一种隔靴搔痒的感觉, 对于内部的三维算法的实现不甚了解. 其 ...

  5. [图形学] 习题8.12 NLN二维线段裁剪算法实现

    Nicholl-Lee-Nicholl二维线段裁剪算法相对于Cohen-Sutherland和Liang-Barsky算法来说,在求交点之前进行了线段端点相对于几个区域的判断,可以确切的知道要求交点的 ...

  6. URAL - 1486 Equal Squares 二维哈希+二分

    During a discussion of problems at the Petrozavodsk Training Camp, Vova and Sasha argued about who o ...

  7. 【URAL 1486】Equal Squares(二维哈希+二分)

    Description During a discussion of problems at the Petrozavodsk Training Camp, Vova and Sasha argued ...

  8. 【BZOJ 2462】矩阵模板 (二维哈希)

    题目 给定一个M行N列的01矩阵,以及Q个A行B列的01矩阵,你需要求出这Q个矩阵哪些在 原矩阵中出现过. 所谓01矩阵,就是矩阵中所有元素不是0就是1. 输入 输入文件的第一行为M.N.A.B,参见 ...

  9. AcWing - 156 矩阵(二维哈希)

    题目链接:矩阵 题意:给定一个$m$行$n$列的$01$矩阵$($只包含数字$0$或$1$的矩阵$)$,再执行$q$次询问,每次询问给出一个$a$行$b$列的$01$矩阵,求该矩阵是否在原矩阵中出现过 ...

随机推荐

  1. Flutter 应用入门:路由管理

    路由(Route)在移动开发中通常指页面(Page),这跟web开发中单页应用的Route概念意义是相同的,Route在Android中通常指一个Activity,在iOS中指一个ViewContro ...

  2. 在Linux系统下限制指定目录的大小以及文件/文件夹数量

    背景说明 在Linux操作系统下有时需要限制一个指定文件夹的大小和文件夹内可存储的文件数量,有可能是出于安全的考量或者定制化的配置,这里我们提供了一种方案:用dd创建一个空的img镜像,进行格式化的配 ...

  3. Manjaro Linux 5.9.11-3安装和配置全局截图工具FlameShot教程

    背景说明 截图工具是日常适用频率较高的一种系统工具,在Linux下也有不少常用截图工具,如deepin-screenshot等,但是今天我们要介绍的是FlameShot--一款更加精致的Linux全局 ...

  4. JavaScript入门-函数function(二)

    JavaScript入门-函数function(二) 递归函数 什么是递归函数? 递归简单理解就是,在函数体里,调用自己. //我们在求一个10的阶乘的时候,可能会这么做 //写一个循环 var to ...

  5. HashMap为什么效率高?来看看这个小demo

    一.前情回顾:在程序中有时候需要存放对象,容器应运而生.容器分为集合和Map.集合在这里不说,说说Map.Map在英语中是地图的意思,这个名字真是起的好,可以让人顾名思义.Map,就是存放键值对的结构 ...

  6. 一文带你学会AQS和并发工具类的关系2

    1.创建公平锁 1.使用方式 Lock reentrantLock = new ReentrantLock(true); reentrantLock.lock(); //加锁 try{ // todo ...

  7. memcached+magent的集群部署详细过程

    问题描述 Memcached在实现分布集群部署时, Memcached服务端的之间是没有通讯的,服务端是伪分布式,实现分布式是由客户端实现的,客户端实现了分布式算法把数据保存到不同的Memcached ...

  8. 【Linux】在文件的指定位置插入数据

    今天遇到一个似乎很棘手的问题,要在文件的中间,插入几条配置 这里就以my.cnf这个文件为例 1 [mysqld] 2 datadir=/var/lib/mysql 3 socket=/var/lib ...

  9. oracle修改表栏位类型

    需求:ID栏位在创建的时候是varchar类型,后续要修改为number类型 因为oracle修改表栏位类型的时候需要栏位内没有数据,因此无法直接把ID从varchar修改为number 1.新建一个 ...

  10. Java自学笔记1206

    字符串比较string1.equals(string2) 代码如下: 1 package Demo_1206; 2 3 import java.util.Scanner; 4 5 public cla ...