二维哈希即可。
注意质数选的大一些,不然会超时。
还有插入的时候不判重居然比判重要快。。
——代码
1 #include <cstdio> 2 int main() 3 { 4 int i = 10; 5 while(i--) puts("1"); 6 return 0; 7 }
O不,错了,是这个。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define UI unsigned int 5 6 const int p = 1000007, MAXN = 1001; 7 int n, m, a, b, q, cnt, head[p], next[MAXN * MAXN]; 8 UI h, sum[MAXN][MAXN], base1[MAXN], base2[MAXN], to[MAXN * MAXN]; 9 10 inline void insert(UI x) 11 { 12 int i, a = x % p; 13 for(i = head[a]; i ^ -1; i = next[i]) 14 if(!(to[i] ^ x)) 15 return; 16 to[cnt] = x; 17 next[cnt] = head[a]; 18 head[a] = cnt++; 19 } 20 21 inline bool find(UI x) 22 { 23 int i, a = x % p; 24 for(i = head[a]; i ^ -1; i = next[i]) 25 if(!(to[i] ^ x)) 26 return 1; 27 return 0; 28 } 29 30 int main() 31 { 32 int i, j; 33 scanf("%d %d %d %d", &n, &m, &a, &b); 34 base1[0] = base2[0] = 1; 35 memset(head, -1, sizeof(head)); 36 for(i = 1; i <= n; i++) base1[i] = base1[i - 1] * 19260817; 37 for(i = 1; i <= m; i++) base2[i] = base2[i - 1] * 20011001; 38 for(i = 1; i <= n; i++) 39 for(j = 1; j <= m; j++) 40 scanf("%1d", &sum[i][j]); 41 for(i = 1; i <= n; i++) 42 for(j = 1; j <= m; j++) 43 sum[i][j] += sum[i - 1][j] * 19260817; 44 for(i = 1; i <= n; i++) 45 for(j = 1; j <= m; j++) 46 sum[i][j] += sum[i][j - 1] * 20011001; 47 for(i = a; i <= n; i++) 48 for(j = b; j <= m; j++) 49 { 50 h = sum[i][j]; 51 h -= sum[i - a][j] * base1[a]; 52 h -= sum[i][j - b] * base2[b]; 53 h += sum[i - a][j - b] * base1[a] * base2[b]; 54 insert(h); 55 } 56 scanf("%d", &q); 57 while(q--) 58 { 59 for(i = 1; i <= a; i++) 60 for(j = 1; j <= b; j++) 61 scanf("%1d", &sum[i][j]); 62 for(i = 1; i <= a; i++) 63 for(j = 1; j <= b; j++) 64 sum[i][j] += sum[i - 1][j] * 19260817; 65 for(i = 1; i <= a; i++) 66 for(j = 1; j <= b; j++) 67 sum[i][j] += sum[i][j - 1] * 20011001; 68 printf("%d ", find(sum[a][b])); 69 } 70 return 0; 71 }