HDU 4763 (KMP)
PS参考:http://m.blog.csdn.net/blog/biboyouyun/12206733
题意:EAEBE这种结构的字符串,求E的最大长度;
分析:我直接就从s.length()/3开始枚举,结果TLE了,正解是KMP,但是string的substr和find能够水过,只能说学弟太强了(TLE了一次就想怎么减时间,而且还是想怎么通过后台数据找时间,而不是找正解)。
PS:目前还没彻底搞懂KMP算法,只是能用模板的程度,next[]数组表示前缀和后缀的最长长度,next [ i ]决定了1 ~ next [ i ]这个子串一定在str中作为后缀出现,那么我们就是要找一个i(从next[n]推来,不行就i = next [ i ] ),要使1 ~ i 在i + 1 ~ str.length() - i 也有这个子串,那么如何保证子串之间不重叠?就是 3 * i <=length 然后枚举2*i到length - i的每一个next[j]看有没有next [ j ] == i 就可以了
1 #include <cstdio> 2 #include <iostream> 3 #include <sstream> 4 #include <cmath> 5 #include <cstring> 6 #include <cstdlib> 7 #include <string> 8 #include <vector> 9 #include <map> 10 #include <set> 11 #include <queue> 12 #include <stack> 13 #include <algorithm> 14 using namespace std; 15 #define ll long long 16 #define _cle(m, a) memset(m, a, sizeof(m)) 17 #define repu(i, a, b) for(int i = a; i < b; i++) 18 #define repd(i, a, b) for(int i = b; i >= a; i--) 19 #define sfi(n) scanf("%d", &n) 20 #define sfl(n) scanf("%I64d", &n) 21 #define pfi(n) printf("%d\n", n) 22 #define pfl(n) printf("%I64d\n", n) 23 #define MAXN 1000005 24 char s[MAXN]; 25 int Next[MAXN]; 26 bool flag[MAXN]; 27 int main() 28 { 29 int T; 30 scanf("%d",&T); 31 while(T--) 32 { 33 scanf("%s", s); 34 int l = strlen(s); 35 int i = 0, j = -1; 36 Next[0] = -1; 37 while(i < l) 38 { 39 while(j != -1 && s[i]!=s[j]) j = Next[j]; 40 Next[++i]=++j; 41 } 42 memset(flag, 0, sizeof(flag)); 43 int t = l; 44 while(t > 0) 45 { 46 if(l >= 2*t) 47 flag[t] = true; 48 t = Next[t]; 49 } 50 int ans = 0; 51 for(int i = l-1; i > 1; i--) 52 { 53 t = i; 54 while(t > 0) 55 { 56 if(flag[t] && l >= i+t && i >= 2*t) 57 { 58 ans = max(ans,t); 59 break; 60 } 61 t = Next[t]; 62 } 63 } 64 printf("%d\n",ans); 65 } 66 return 0; 67 }
1 #include <cstdio> 2 #include <iostream> 3 #include <sstream> 4 #include <cmath> 5 #include <cstring> 6 #include <cstdlib> 7 #include <string> 8 #include <vector> 9 #include <map> 10 #include <set> 11 #include <queue> 12 #include <stack> 13 #include <algorithm> 14 using namespace std; 15 #define ll long long 16 #define _cle(m, a) memset(m, a, sizeof(m)) 17 #define repu(i, a, b) for(int i = a; i < b; i++) 18 #define repd(i, a, b) for(int i = b; i >= a; i--) 19 #define sfi(n) scanf("%d", &n) 20 #define sfl(n) scanf("%I64d", &n) 21 #define pfi(n) printf("%d\n", n) 22 #define pfl(n) printf("%I64d\n", n) 23 #define MAXN 1000005 24 int main() 25 { 26 ios::sync_with_stdio(false); 27 string s; 28 int T; 29 cin>>T; 30 while(T--) 31 { 32 cin>>s; 33 int l = s.length(); 34 int h = l/3,t = 0; 35 for(int i=h; i>=1; i--) 36 { 37 if(s[i-1] != s[l-1])///数据太水了,加上这个优化就可以过,否则TLE 38 { 39 continue; 40 } 41 string s1 = s.substr(0,i); 42 int j = l - i; 43 string s2 = s.substr(j,i); 44 if(s1 == s2) 45 { 46 s2 = s.substr(i,l-2*i); 47 if(s2.find(s1) != s2.npos) 48 { 49 t = i; 50 break; 51 } 52 } 53 } 54 cout<<t<<endl; 55 } 56 return 0; 57 }
如果想理解的更深一步的话,推荐题目HDU3746
人生就像心电图,想要一帆风顺,除非game-over