wenbao与字符串Hash
------------------------------
http://begin.lydsy.com/JudgeOnline/problem.php?id=1729
N*M字符矩阵中找出至少两个相同的正方形,要求边长尽量长
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 5 #define ll long long 6 const int maxn = 505; 7 const ll D = 97, D2 = 131; 8 int n, m; 9 ll p[maxn], p2[maxn], hs[maxn*maxn], h[maxn][maxn]; 10 char a[maxn][maxn]; 11 12 bool ok(int x){ 13 for(int i = 1; i <= n; ++i){ 14 ll tmp = 0; 15 for(int j = 1; j < x; ++j) tmp = tmp*D + a[i][j], h[i][j] = 0; 16 for(int j = x; j <= m; ++j) h[i][j] = tmp = tmp*D - p[x]*a[i][j-x] + a[i][j]; 17 } 18 int num = 0; 19 for(int i = x; i <= m; ++i){ 20 ll tmp = 0; 21 for(int j = 1; j < x; ++j) tmp = tmp*D2 + h[j][i]; 22 for(int j = x; j <= n; ++j) hs[num++] = tmp = tmp*D2 - p2[x]*h[j-x][i] + h[j][i]; 23 } 24 sort(hs, hs+num); 25 for(int i = 1; i < num; ++i) if(hs[i] == hs[i-1]) return true; 26 return false; 27 } 28 int main(){ 29 scanf("%d%d", &n, &m); 30 for(int i = 1; i <= n; ++i){ 31 scanf("%s", a[i]+1); 32 for(int j = 1; j <= m; ++j) a[i][j] -= 'a'; 33 } 34 int l = 0, r = (n < m ? n : m), sum = 0; 35 p[0] = 1, p2[0] = 1; 36 for(int i = 1; i <= r; ++i) p[i] = p[i-1]*D, p2[i] = p2[i-1]*D2; 37 while(l <= r){ 38 int mid = (l+r)>>1; 39 if(ok(mid)) sum = mid, l = mid+1; 40 else r = mid-1; 41 } 42 printf("%d\n", sum); 43 return 0; 44 }
-----------------------------------------------
http://acm.scu.edu.cn/soj/problem.action?id=4438
1 #include <iostream> 2 #include <string.h> 3 using namespace std; 4 5 #define ll long long 6 const int maxn = 5e6+10; 7 char str[maxn], ss[maxn], st[maxn]; 8 ll p, D = 97, a[maxn]; 9 10 int main(){ 11 while(~scanf("%s%s", str, ss)){ 12 ll aim = 0; 13 p = 1; 14 int len1 = strlen(str), len2 = strlen(ss); 15 for(int i = 0; i < len1; ++i){ 16 aim = aim*D + str[i]-'a'; 17 p *= D; 18 } 19 ll tmp = 0; 20 int top = 0; 21 for(int i = 0; i < len2; ++i){ 22 st[top] = ss[i]; 23 tmp = tmp*D + ss[i] - 'a'; 24 a[++top] = tmp; 25 if(top >= len1 && tmp - a[top-len1]*p == aim){ 26 //cout<<i<<"***"<<endl; 27 tmp = a[top-len1]; 28 top -= len1; 29 } 30 } 31 st[top] = '\0'; 32 printf("%s\n", st); 33 } 34 return 0; 35 }
--------------------------------------------
只有不断学习才能进步!