2351: [BeiJing2011]Matrix( hash )

hash一下, 把原矩阵所有A*B的子矩阵的hash值存在set里面, 然后对于每个询问就求出hash值, 在set中查找. 

------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<set>
#include<algorithm>
 
using namespace std;
 
typedef unsigned long long ull;
 
const int maxn = 1009;
const int p = 31, _p = 59;
 
char str[maxn];
int N, M, n, m;
ull h[maxn][maxn], Power, H[maxn];
set<int> S;
 
ull get(int x, int y) {
return h[x][y] - h[x][y + m] * Power;
}
 
void init() {
scanf("%d%d%d%d", &N, &M, &n, &m);
for(int i = 0; i < N; i++) {
scanf("%s", str);
h[i][M] = 0;
for(int j = M; j--; )
h[i][j] = h[i][j + 1] * p + str[j];
}
Power = 1;
for(int i = 1; i <= m; i++) Power = Power * p;
S.clear();
for(int i = N - n; i >= 0; i--)
for(int j = M - m; j >= 0; j--) {
ull t = 0;
for(int k = i; k < i + n; k++) t = t * _p + get(k, j);
S.insert(t);
}
}
 
int main() {
init();
int Q; scanf("%d", &Q);
while(Q--) {
ull res = 0;
for(int i = 0; i < n; i++) {
ull H = 0;
scanf("%s", str);
for(int j = m; j--; )
H = H * p + str[j];
res = res * _p + H;
}
printf("%d\n", S.find(res) != S.end());
}
return 0;
}

------------------------------------------------------------------------ 

 

2351: [BeiJing2011]Matrix

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 705  Solved: 200
[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

posted @ 2015-10-22 22:05  JSZX11556  阅读(412)  评论(0编辑  收藏  举报