UVa 11019 Matrix Matcher - Hash
阿新 • • 發佈:2018-03-24
target 快速 傳送門 ng- main option col cst ron
題目傳送門
快速的vjudge傳送門
快速的UVa傳送門
題目大意
給定兩個矩陣S和T,問T在S中出現了多少次。
不會AC自動機做法。
考慮一維的字符串Hash怎麽做。
對於一個長度為$l$的字符串$s$,它的Hash值$hash(s) = \sum_{i = 1}^{l}x^{l - i}s_{i}$。
對於二維的情況,我們就取兩個基,$x, y$,對於一個$n\times m$的矩陣$A$的Hash值可以表示為
$hash(A) = \sum_{i = 1}^{n}\sum_{j = 1}^{m}x^{n - i}y^{m - j}a_{ij}$
然後以記錄$S$的左上角的左上角的所有子矩陣的hash值(這個可以$O(1)$轉移)。詢問一個子矩陣的hash值,就可以$O(1)$回答。
接下來就很簡單了。枚舉每個位置判斷是否匹配。
Code
1 /** 2 * UVa 3 * Problem#11019 4 * Accepted 5 * Time: 50ms 6 */ 7 #include <iostream> 8 #include <cstdlib> 9 #include <cstdio> 10 using namespace std; 11typedef bool boolean; 12 13 const unsigned int hash1 = 200379, hash2 = 211985; 14 const int N = 1005, M = 105; 15 16 int p1[N], p2[N]; 17 int m, n, x, y; 18 char S[N][N], T[M][M]; 19 unsigned int hs[N][N]; 20 21 inline void prepare() { 22 p1[0] = 1, p2[0] = 1; 23 for (int i = 1; i < N; i++)24 p1[i] = p1[i - 1] * hash1; 25 for (int i = 1; i < N; i++) 26 p2[i] = p2[i - 1] * hash2; 27 } 28 29 inline void init() { 30 scanf("%d%d", &n, &m); 31 for (int i = 1; i <= n; i++) 32 scanf("%s", S[i] + 1); 33 scanf("%d%d", &x, &y); 34 for (int i = 1; i <= x; i++) 35 scanf("%s", T[i] + 1); 36 } 37 38 inline void solve() { 39 for (int i = 1; i <= n; i++) 40 for (int j = 1; j <= m; j++) { 41 hs[i][j] = hs[i - 1][j - 1] * hash1 * hash2 + (hs[i - 1][j] - hs[i - 1][j - 1] * hash2) * hash1 + (hs[i][j - 1] - hs[i - 1][j - 1] * hash1) * hash2 + S[i][j]; 42 } 43 44 /* unsigned int s1 = 0; 45 for (int i = 1; i <= n; i++) 46 for (int j = 1; j <= m; j++) 47 s1 += S[i][j] * p1[n - i] * p2[m - j]; 48 49 cerr << s1 << " " << (97u * 200379 * 211985 + 98u * 200379 + 98u * 211985 + 97) << " " << hs[2][2] << endl;*/ 50 51 int rt = 0; 52 unsigned int s = 0, c; 53 for (int i = 1; i <= x; i++) 54 for (int j = 1; j <= y; j++) 55 s += T[i][j] * p1[x - i] * p2[y - j]; 56 // cerr << s << endl; 57 for (int i = x; i <= n; i++) 58 for (int j = y; j <= m; j++) { 59 c = hs[i][j] - hs[i - x][j - y] * p1[x] * p2[y] - (hs[i][j - y] - hs[i - x][j - y] * p1[x]) * p2[y] - (hs[i - x][j] - hs[i - x][j - y] * p2[y]) * p1[x]; 60 if (s == c) 61 rt++; 62 } 63 printf("%d\n", rt); 64 } 65 66 int kase; 67 int main() { 68 prepare(); 69 scanf("%d", &kase); 70 while (kase--) { 71 init(); 72 solve(); 73 } 74 return 0; 75 }
UVa 11019 Matrix Matcher - Hash