[bzoj2351][BeiJing2011]Matrix 哈希

来源:互联网 发布:三国书籍知乎 编辑:程序博客网 时间:2024/06/08 15:29

2351: [BeiJing2011]Matrix

Time Limit: 20 Sec  Memory Limit: 128 MB
[Submit][Status][Discuss]

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

HINT

对于100%的实际测试数据,M、N ≤ 1000,Q = 1000

对于40%的数据,A = 1。

对于80%的数据,A ≤ 10。

对于100%的数据,A ≤ 100。

Source

这道题需要用到蛤希,以前我蛤希都是乱打的(就是乱打一个数组再乱存),这次学了一下模板
01矩阵嘛,我们需要用到乘去抵消,去产生
蛤什么数的话,乱打,只要不是向我一样幸运E就行了,事实上应该研究一下怎么膜
大家看我for了m*m,还A了,数据水
#include<iostream>#include<cstdio>#define base1 16446473#define base2 12378657#define mod 10007const int N = 1000 + 5;using namespace std;int n,m,q,a,b;unsigned int sum[N][N],h[N],l[N],last[mod],cnt;struct data{unsigned w; int next;}e[N*N];void insert( unsigned int x ){e[++cnt].w = x; e[cnt].next = last[x%mod]; last[x%mod] = cnt;}bool check( unsigned int x ){int x1 = x%mod;for( int i = last[x1]; i; i = e[i].next )if( e[i].w == x ) return true;return false;}int main(){scanf("%d%d%d%d", &m, &n, &a, &b);for( int i = 1; i <= m; i++ ) for( int j = 1; j <= m; j++ ) scanf("%1d", &sum[i][j]);for( int i = 1; i <= m; i++ ) for( int j = 1; j <= m; j++ ) sum[i][j] += sum[i-1][j]*base1;for( int i = 1; i <= m; i++ ) for( int j = 1; j <= m; j++ ) sum[i][j] += sum[i][j-1]*base2;h[0] = l[0] = 1;for( int i = 1; i <= max(m,n); i++ ) h[i] = h[i-1]*base1, l[i] = l[i-1]*base2;for( int i = a; i <= m; i++ ) for( int j = b; j <= n; j++ ){unsigned int seed = sum[i][j]-sum[i-a][j]*h[a]-sum[i][j-b]*l[b]+sum[i-a][j-b]*l[b]*h[a];insert( seed );}scanf("%d", &q);while( q-- ){for( int i = 1; i <= a; i++ ) for( int j = 1; j <= b; j++ ) scanf("%1d", &sum[i][j]);for( int i = 1; i <= a; i++ ) for( int j = 1; j <= b; j++ ) sum[i][j] += sum[i-1][j]*base1;for( int i = 1; i <= a; i++ ) for( int j = 1; j <= b; j++ ) sum[i][j] += sum[i][j-1]*base2;puts(check(sum[a][b])?"1":"0");}return 0;}


原创粉丝点击