[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
111
000
111
3
11
00
11
11
00
11
Sample Output
1
0
1A,B<=1
0
1A,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