题目链接:https://vjudge.net/problem/HDU-4763
Theme Section
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4264 Accepted Submission(s): 2056
To get well prepared for the festival, the hosts want to know the maximum possible length of the theme section of each song. Can you help us?
题解:
给定一个字符串,找出能构成"EAEBE"形式的字符串的E的最长长度。其中A和B任意。
1.可知next[len]就是:即是前缀又是后缀的最长子串。所以我们就解决的首尾两个E(如果大于三分之一长度,可以通过next数组回退)。
2.剩下的问题就是:在两个E之间的连续子串中,是否能找到第三个E。
3.怎么找到?枚举里面的每个位置(注意不能与首尾的E有重叠),通过next数组的回退,一直找。详情还是看代码吧。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <string> 6 #include <vector> 7 #include <map> 8 #include <set> 9 #include <queue> 10 #include <sstream> 11 #include <algorithm> 12 using namespace std; 13 typedef long long LL; 14 const double eps = 1e-6; 15 const int INF = 2e9; 16 const LL LNF = 9e18; 17 const int MOD = 1e9+7; 18 const int MAXN = 1e6+10; 19 20 char x[MAXN]; 21 int Next[MAXN]; 22 23 void get_next(char x[], int m) 24 { 25 int i, j; 26 j = Next[0] = -1; 27 i = 0; 28 while(i<m) 29 { 30 while(j!=-1 && x[i]!=x[j]) j = Next[j]; 31 Next[++i] = ++j; 32 } 33 } 34 35 int main() 36 { 37 int T; 38 scanf("%d", &T); 39 while(T--) 40 { 41 scanf("%s", x); 42 int len = strlen(x); 43 get_next(x, len); 44 int r = Next[len]; 45 while(r>0 && len/r<3) r = Next[r]; 46 47 bool hav_ans = false; 48 for(; Next[r]>=1; r = Next[r]) 49 { 50 for(int i = 2*r; i<=len-r; i++) 51 { 52 int k = i; //不要写成Next[i]; 53 while(Next[k]>r) k = Next[k]; 54 if(Next[k]==r) 55 { 56 hav_ans = true; 57 break; 58 } 59 } 60 if(hav_ans) break; 61 } 62 printf("%d\n", r); 63 } 64 }