博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
字符串哈希(二维)-Constellations POJ - 3690
阅读量:358 次
发布时间:2019-03-04

本文共 2664 字,大约阅读时间需要 8 分钟。

字符串哈希(二维)-Constellations POJ - 3690

公 式 推 导 公式推导 ——《》

题意:

输 入 一 个 n × m 的 由 ′ ∗ ′ 和 ′ 0 ′ 构 成 的 矩 阵 M 0 , 接 着 输 入 q 个 a × b 的 矩 阵 ( a < = n , b < = m ) , 求 这 q 个 矩 阵 中 , 有 多 少 个 矩 阵 是 M 0 的 子 矩 阵 。 输入一个n×m的由'*'和'0'构成的矩阵M_0,接着输入q个a×b的矩阵(a<=n,b<=m),\\求这q个矩阵中,有多少个矩阵是M_0的子矩阵。 n×m0M0qa×b(a<=n,b<=m)qM0

样例及数据范围:

在这里插入图片描述
1 < = n , m < = 1000 , 1 < = q < = 100 , 1 < = a , b < = 50 。 1<=n,m<=1000,1<=q<=100,1<=a,b<=50。 1<=n,m<=10001<=q<=1001<=a,b<=50

具体落实:

① 、 可 以 在 输 入 n × m 的 矩 阵 的 同 时 , 对 其 每 一 行 单 独 进 行 哈 希 , 为 ③ 预 处 理 准 备 。 ② 、 再 求 q 个 小 矩 阵 的 哈 希 值 , 用 m u l t i s e t 来 保 存 。 ③ 、 然 后 求 整 个 n × m 的 矩 阵 中 所 有 的 a × b 的 子 矩 阵 的 哈 希 值 , 同 时 在 m u l t i s e t 中 删 除 对 应 的 元 素 。 ④ 、 最 后 m u l t i s e t 中 剩 下 没 有 被 删 掉 的 元 素 就 是 未 能 匹 配 成 功 的 子 矩 阵 , 答 案 为 输 入 的 子 矩 阵 的 个 数 q 减 去 容 器 中 剩 余 元 素 的 个 数 。 ①、可以在输入n×m的矩阵的同时,对其每一行单独进行哈希,为③预处理准备。\\②、再求q个小矩阵的哈希值,用multiset来保存。\\③、然后求整个n×m的矩阵中所有的a×b的子矩阵的哈希值,同时在multiset中删除对应的元素。\\④、最后multiset中剩下没有被删掉的元素就是未能匹配成功的子矩阵,\\\qquad答案为输入的子矩阵的个数q减去容器中剩余元素的个数。 n×mqmultisetn×ma×bmultisetmultisetq

因 为 P O J 不 支 持 u n o r d e r e d _ s e t , 所 以 本 题 采 用 了 m u l t i s e t 。 另 外 , u n s i g n e d   i n t 处 理 起 来 要 比 u n s i g n e d   l o n g   l o n g 要 快 一 些 , 但 冲 突 概 率 会 大 一 些 。 因为POJ不支持unordered\_set,所以本题采用了multiset。\\另外,unsigned\ int处理起来要比unsigned\ long\ long要快一些,但冲突概率会大一些。 POJunordered_setmultisetunsigned intunsigned long long

神 奇 发 现 : 似 乎 对 容 器 只 进 行 删 除 插 入 操 作 要 比 询 问 要 快 . . . 神奇发现:似乎对容器只进行删除插入操作要比询问要快... ...


代码:

#include
#include
#include
#include
#include
#define ull unsigned intusing namespace std;const int N=1010;const int base=131;int n,m,q,a,b;ull h[N][N],p[2510];char str[N];ull get(ull h[],int l,int r){
return h[r]-h[l-1]*p[r-l+1];}int main(){
int T=1; while(~scanf("%d%d%d%d%d",&n,&m,&q,&a,&b),n||m||q||a||b) {
multiset
S; for(int i=1;i<=n;i++) { scanf("%s",str+1); for(int j=1;j<=m;j++) h[i][j]=h[i][j-1]*base+str[j]-'0'; } p[0]=1; for(int i=1;i<=a*b;i++) p[i]=p[i-1]*base; for(int k=1;k<=q;k++) { ///计算输入的子矩阵的值 ull s=0; for(int i=1;i<=a;i++) { scanf("%s",str+1); for(int j=1;j<=b;j++) s=s*base+str[j]-'0'; } S.insert(s); } ///j枚举右端点,求所有a×b的子矩阵哈希值 for(int j=b;j<=m;j++) { ull s=0; int l=j-b+1,r=j; for(int i=1;i<=n;i++) ///按列求哈希 { s=s*p[b]+get(h[i],l,r); if(i-a>0) s-=get(h[i-a],l,r)*p[a*b]; if(i-a>=0) S.erase(s); } } printf("Case %d: %d\n",T++,q-S.size()); } return 0;}

转载地址:http://bjor.baihongyu.com/

你可能感兴趣的文章