[BZOJ2462][BeiJing2011]矩阵模板

Description

给定一个M行N列的01矩阵,以及Q个A行B列的01矩阵,你需要求出这Q个矩阵哪些在
原矩阵中出现过。
   所谓01矩阵,就是矩阵中所有元素不是0就是1。 
 

Input

输入文件的第一行为M、N、A、B,参见题目描述。
接下来M行,每行N个字符,非0即1,描述原矩阵。
接下来一行为你要处理的询问数Q。
接下来Q个矩阵,一共Q*A行,每行B个字符,描述Q个01矩阵。 
 

Output

你需要输出Q行,每行为0或者1,表示这个矩阵是否出现过,0表示没有出现过,1表
示出现过。

Sample Input

3 3 2 2
111
000
111
3
11
00
11
11
00
11

Sample Output

1
0
1
A,B<=1

 

 


 

这题卡常!!!!!!

把读入单个数字改成读入字符串,把map改成数组...

先求列的hash值,再在这个基础上加上行的hash值,得到的是从(1,1)到(i,j)的矩阵的hash值,然后取出一个矩阵就类比二维前缀和...

 


 

 

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
#define reg register
inline int read() {
    int res = 0;char ch=getchar();bool fu=0;
    while(!isdigit(ch))fu|=(ch=='-'), ch=getchar();
    while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48), ch=getchar();
    return fu?-res:res;
}
#define N 100005
#define mod 1000006
int n, m, A, B;
unsigned long long hsh[1005][1005], kp1[1005], kp2[1005];
int a[1005][1005];
char str[1005];
bool mp[1000006];


int main()
{
    n = read(), m = read(), A = read(), B = read();
    for (reg int i = 1 ; i <= n ; i ++) {
        scanf("%s", str + 1);
        for (reg int j = 1 ; j <= m ; j ++)
            a[i][j] = str[j] - '0';
    }
        
    kp1[0] = kp2[0] = 1;
    for (reg int i = 1 ; i <= 100 ; i ++) kp1[i] = kp1[i - 1] * 233, kp2[i] = kp2[i - 1] * 313;
    for (reg int i = 1 ; i <= n ; i ++)
        for (reg int j = 1 ; j <= m ; j ++)
            hsh[i][j] = hsh[i - 1][j] * 233 + a[i][j];
    for (reg int i = 1 ; i <= n ; i ++)
        for (reg int j = 1 ; j <= m ; j ++)
            hsh[i][j] += hsh[i][j - 1] * 313;
    for (reg int i = A ; i <= n ; i ++)
        for (reg int j = B ; j <= m ; j ++) {
            unsigned long long tmp = 0;
            tmp = hsh[i][j] - hsh[i - A][j] * kp1[A] - hsh[i][j - B] * kp2[B] + hsh[i - A][j - B] * kp1[A] * kp2[B];
            mp[tmp%mod] = 1;
        }
    int q = read();
    while(q--)
    {
        for (reg int i = 1 ; i <= A ; i ++) {
            scanf("%s", str + 1);
            for (reg int j = 1 ; j <= B ; j ++)
                a[i][j] = str[j] - '0';
        }
        memset(hsh, 0, sizeof hsh);
        for (reg int i = 1 ; i <= A ; i ++)
            for (reg int j = 1 ; j <= B ; j ++)
                hsh[i][j] = hsh[i - 1][j] * 233 + a[i][j];
        for (reg int i = 1 ; i <= A ; i ++)
            for (reg int j = 1 ; j <= B ; j ++)
                hsh[i][j] += hsh[i][j - 1] * 313;
        puts(mp[hsh[A][B] % mod] ? "1" : "0");
    }
    return 0;
}

 

 

 

00

posted @ 2018-10-18 15:42  zZhBr  阅读(175)  评论(0编辑  收藏  举报