156. 矩阵[二维的hash]
给定一个M行N列的01矩阵(只包含数字0或1的矩阵),再执行Q次询问,每次询问给出一个A行B列的01矩阵,求该矩阵是否在原矩阵中出现过。
输入格式
第一行四个整数M,N,A,B。
接下来一个M行N列的01矩阵,数字之间没有空格。
接下来一个整数Q。
接下来Q个A行B列的01矩阵,数字之间没有空格。
输出格式
对于每个询问,输出1表示出现过,0表示没有出现过。
数据范围
A≤100<?XML:NAMESPACE PREFIX = "[default] http://www.w3.org/1998/Math/MathML" NS = "http://www.w3.org/1998/Math/MathML" />A≤100,M,N,B≤1000M,N,B≤1000,Q≤1000Q≤1000
输入样例:
3 3 2 2
111
000
111
3
11
00
11
11
00
11
输出样例:
1
0
1
首先,此题是一维hash的拓展。
我们可以通过先将每一行hash完成,然后通过枚举a,b大小的矩阵,计算hash值,通过公式推导,
a列到a+1列的公式是,s = s*p^b + get(h[j], l, r);也就是该行的hash值。
最后给出代码:
#include <iostream> #include <algorithm> #include <unordered_set> using namespace std; using ULL = unsigned long long; const int N = 1010, M = N*N, base = 131; char str[N]; ULL h[N][N], p[M]; int n, m, a, b; ULL get(ULL h[], int l, int r){ return h[r] - h[l - 1] * p[r - l + 1]; } int main() { cin >> n >> m >> a >> b; p[0] = 1; for(int i = 1; i <= n*m; ++ i) p[i] = p[i-1] * base;//对应的进制数的幂 for(int i = 1; i <= n; ++ i) {//处理行并hash cin >> (str+1); for(int j = 1; j <= m; ++ j)h[i][j] = h[i][j - 1] * base + str[j] - '0'; } unordered_set<ULL> S; for(int i = b; i <= m; ++ i) {//处理每个矩形hash值。 ULL s = 0; int l = i - b + 1, r = i; for(int j = 1; j <= n; ++ j){ s = s * p[b] + get(h[j], l, r); if(j > a) s -= get(h[j - a], l, r) * p[a*b]; if(j >= a) S.insert(s); } } int k; cin >> k; while(k --) { ULL s = 0; for(int i = 1; i <= a; ++ i) {//处理输入要查找的矩形,计算hash值 cin >> (str+1); for(int j = 1; j <= b; ++ j) s = s*base + str[i] - '0'; } if(S.count(s))puts("1");//看是否在集合中 else puts("0"); } return 0; }
追求吾之所爱
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Linux系统下SQL Server数据库镜像配置全流程详解
· 现代计算机视觉入门之:什么是视频
· 你所不知道的 C/C++ 宏知识
· 不到万不得已,千万不要去外包
· C# WebAPI 插件热插拔(持续更新中)
· 会议真的有必要吗?我们产品开发9年了,但从来没开过会
· 【译】我们最喜欢的2024年的 Visual Studio 新功能
· 如何打造一个高并发系统?