BZOJ 2462 BeiJing 2011 矩阵模板 二维hash

题目大意:给出一个m*n的由01组成的矩阵,下面有q个询问,查询矩阵中存不存在大小为k*l的子矩阵。

思路:二维hash。我们先把大矩阵hash,然后把所有可能的k*l的子矩阵都插到哈希表里,然后只要对于每个询问hash一下看哈希表中是否存在。

值得一提的是,这个题只需要输出10个1就可以AC了。。

CODE:

#include <cstdio>
#include <bitset>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 1100
using namespace std;
const unsigned int BASE1 = 10016957;
const unsigned int BASE2 = 10016957;
const int MO = 99999997;

int m,n,ask_m,ask_n,asks;
unsigned int hash[MAX][MAX],_hash[MAX][MAX];
unsigned int pow1[MAX],pow2[MAX];

bool set[100000000];

inline unsigned int GetHash()
{
    for(int i = 1; i <= ask_m; ++i)
        for(int j = 1; j <= ask_n; ++j)
            _hash[i][j] += _hash[i - 1][j] * BASE1;
    for(int i = 1; i <= ask_m; ++i)
        for(int j = 1; j <= ask_n; ++j)
            _hash[i][j] += _hash[i][j - 1] * BASE2;
    return _hash[ask_m][ask_n];
}

int main()
{
    cin >> m >> n >> ask_m >> ask_n;
    for(int i = 1; i <= m; ++i)
        for(int j = 1; j <= n; ++j)
            scanf("%1d",&hash[i][j]);
    pow1[0] = pow2[0] = 1;
    for(int i = 1; i <= 100; ++i)
        pow1[i] = pow1[i - 1] * BASE1,pow2[i] = pow2[i - 1] * BASE2;
    for(int i = 1; i <= m; ++i)
        for(int j = 1; j <= n; ++j)
            hash[i][j] += hash[i - 1][j] * BASE1;
    for(int i = 1; i <= m; ++i)
        for(int j = 1; j <= n; ++j)
            hash[i][j] += hash[i][j - 1] * BASE2;
    for(int i = ask_m; i <= m; ++i)
        for(int j = ask_n; j <= n; ++j) {
            unsigned int h = hash[i][j];
            h -= hash[i - ask_m][j] * pow1[ask_m];
            h -= hash[i][j - ask_n] * pow2[ask_n];
            h += hash[i - ask_m][j - ask_n] * pow1[ask_m] * pow2[ask_n];
            set[h % MO] = true;
        }
    for(cin >> asks; asks--;) {
        for(int i = 1; i <= ask_m; ++i)
            for(int j = 1; j <= ask_n; ++j)
                scanf("%1d",&_hash[i][j]);
        puts(set[GetHash() % MO] ? "1":"0");
    }
    return 0;
}

时间: 2024-11-05 18:50:39

BZOJ 2462 BeiJing 2011 矩阵模板 二维hash的相关文章

根据矩阵的二维相关系数进行OCR识别

我想通过简单的模板匹配来进行图像识别. 把预处理好的字符图片,分别与A到J的样本图片进行模板匹配.结果最大的表明相关性最大,就可以识别字符图片了. 在实际应用中,我用了openCV的matchTemplate()函数,但是未达到我想要点的效果. matchTemplate()的功能是在图像中搜索出指定的模板,如果模板是从待搜索的图像中截取出来的,会有很好的效果.但是如果模板不是待搜素图像的一部分,似乎达不到我想要的效果. 在尝试了matlab的corr2()后,发现corr2能很好的解决我的问题

【c语言】二维数组中的查找,杨氏矩阵在一个二维数组中,每行都依照从左到右的递增的顺序排序,输入这种一个数组和一个数,推断数组中是否包括这个数

// 二维数组中的查找,杨氏矩阵在一个二维数组中.每行都依照从左到右的递增的顺序排序. // 每列都依照从上到下递增的顺序排序.请完毕一个函数,输入这种一个数组和一个数.推断数组中是否包括这个数 #include <stdio.h> #define col 4 #define rol 4 int yang(int(*p)[col], int num) { int i = 0; int j = col - 1; while (j+1) { int *q = &(p[i][j]); if

BZOJ 1567 Blue Mary的战役地图(二维hash+二分)

题意: 求两个矩形最大公共子正方形.(n<=50) 范围这么小可以枚举子正方形的边长.那么可以对这个矩形进行二维hash,就可以在O(1)的时候求出任意子矩形的hash值.然后判断这些正方形的hash值有没有相同的 部分就行了.可以用二分来判断. 需要注意的是行和列乘的hash种子值需要不同的质数,否则可能出现冲突. 时间复杂度O(n^3logn). # include <cstdio> # include <cstring> # include <cstdlib>

URAL 1486 Equal Squares 二维Hash

Hash在信息学竞赛中的一类应用 论文中的第一道例题,关于二维hash的一些处理方法和小技巧 通过RK法计算hash值如果不取模的话可以O(n)预处理,然后O(1)得到任意一个字串的hash值 得到任意子串的hash值的时候不能用除和取模运算了,显然是错的 二维hash如果使用RK法每一次的p值必须不一样 如果不能确定hash值一定不是唯一的,可以计算一个用来确定pos 的hash值和一个用来确定值的hash值 代码写的相当挫,不忍直视 #include <cstdio> #include &

计蒜客模拟赛D1T1 蒜头君打地鼠:矩阵旋转+二维前缀和

题目链接:https://nanti.jisuanke.com/t/16445 题意: 给你一个n*n大小的01矩阵,和一个k*k大小的锤子,锤子只能斜着砸,问只砸一次最多能砸到多少个1. 题解: 将原矩阵顺时针旋转45°,二维前缀和预处理,然后枚举每一个可能砸到的正方形之和并取最大. 注:枚举的正方形的四个顶点必须是从原矩阵璇转过来的点,代码中用vis数组判断. #include <iostream> #include <stdio.h> #include <string.

HDU 2642(树状数组模板二维)

Stars Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/65536 K (Java/Others) Total Submission(s): 1350    Accepted Submission(s): 554 Problem Description Yifenfei is a romantic guy and he likes to count the stars in the sky. To make the

BZOJ 2748: [HAOI2012]音量调节【二维dp,枚举】

2748: [HAOI2012]音量调节 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 2010  Solved: 1260[Submit][Status][Discuss] Description 一个吉他手准备参加一场演出.他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都要改变一次音量.在演出开始之前,他已经做好了一个列表,里面写着在每首歌开始之前他想要改变的音量是多少.每一次改变音量,他可以选择调高也可以调低. 音量用一个整数描

BZOJ 1513 POI 2006 Tet-Tetris 3D 二维线段树

题目大意:三维俄罗斯方块,问最后摞了多高. 思路:二维线段树的裸题.但是要注意二维线段树不支持标记下穿.所以就不下传,每次更新答案的时候先看标记,然后用所有的跟标记比较大小之后返回. 具体看代码吧,不知道怎么说. CODE: #define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define

[luoguP2601] [ZJOI2009]对称的正方形(二维Hash + 二分 || Manacher)

传送门 很蒙蔽,不知道怎么搞. 网上看题解有说可以哈希+二分搞,也有的人说用Manacher搞,Manacher是什么鬼?以后再学. 对于这个题,可以从矩阵4个角hash一遍,然后枚举矩阵中的点,再二分半径. 但是得考虑边的长度为奇偶所带来的影响. 比如 1 1 1 1 这个边数为偶数的矩阵显然没法搞. 所以得在矩阵中插入0, 变成 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 具体操作就看代码好了. 然后只枚举 行 + 列 为偶数的点就行.