wenbao与manacher

推荐博客:https://segmentfault.com/a/1190000003914228

 

----------------------------------------------------

模板

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 using namespace std;
 5 const int maxn = 1e6+10;
 6 char str[2*maxn];
 7 int b[2*maxn];
 8 
 9 int main() {
10     int n;
11     scanf("%d", &n);
12     while(n--) {
13         scanf("%s", str);
14         int len = strlen(str), j = 0, ma = 0;
15         for(int i = len; i >= 0; i--) {
16             str[2*i+2] = str[i];
17             str[i*2+1] = '#';
18         }
19         str[0] = '@';
20         for(int i = 2; i <2*len+1; i++) {
21             if(j+b[j] > i) b[i] = min(b[2*j-i], j+b[j]-i); //i在pos左边
22             else b[i] = 1;//i在pos右边
23             while(str[i-b[i]] == str[i+b[i]]) b[i]++;
24             if(j+b[j] < i+b[i]) j = i;//最长的中心位置
25             if(ma < b[i]) ma = b[i];//回文串的最长长度+1
26         }
27         printf("%d
", ma-1);
28     }
29     return 0;
30 }

------------------------------------------------------

小刘

 1 #include <iostream>
 2 #include <string.h>
 3 using namespace std;
 4 const int maxn = 1e6+10;
 5 char str[maxn];
 6 int main(){
 7     int n;
 8     cin>>n;
 9     while( n -- ){
10     memset( str, 0, sizeof( str ) );
11     cin>>str;
12     int len = strlen(str),man = -1,j;
13     for( int i = 0; i < len; i ++ ){
14         for( j = 0; i - j >= 0 && i + j < len; j ++ ){
15             if( str[i-j] != str[i+j] ) break;
16         }
17         man = max( man, 2 * j - 1) ;
18         for( j = 0; i - j >= 0 && i + j + 1 < len; j ++ ){
19             if( str[i - j] != str[i + j + 1] ) break;
20         }
21         man = max( man, 2 * j  );
22     }
23     cout<<man<<endl;
24     }
25 }

输出最大回文子串

 1 #include <iostream>
 2 #include <ctype.h>
 3 #include <stdio.h>
 4 #include <string.h>
 5 using namespace std;
 6 const int maxn = 110000+10;
 7 char str[maxn], s[maxn];
 8 int p[maxn];
 9 int main(){
10     int len, m = 0, man = 0, x, y;
11     int i, j;
12     fgets(str, 1000, stdin); //fgets(s, n, stdin); 从键盘读入长度为不大于n的字符完美替代gets
13     // cout<<s<<endl;
14     len = strlen(str);
15     for(i = 0; i < len; i ++){
16         if(isalpha(str[i])){
17             p[m] = i;
18             s[m++] = toupper(str[i]);
19         }
20     }
21     // cout<<s<<endl;
22     // cout<<m<<endl;
23     for(i = 0; i < m; i ++){
24         for(j = 0; i - j >= 0 && i + j < m; j ++){
25             if(s[i-j] != s[i+j]) break;
26             if(man < 2*j+1) man = 2*j+1, x = p[i-j], y = p[i+j];
27         }
28         for(j = 0; i - j >= 0 && i + j + 1 < m; j ++){
29             if(s[i - j] != s[i + j + 1]) break;
30         if(man < 2*j+2) man = 2*j+2, x = p[i-j], y = p[i+j+1]; 
31         }
32     }
33     for(i = x; i <= y; i ++){
34         printf("%c", str[i]);
35     }
36     printf("
");
37     return 0;
38 }

 --------------------------------------------------------------

http://acm.timus.ru/problem.aspx?space=1&num=1297

 输出最长回文串

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 using namespace std;
 5 
 6 const int maxn=1e3+10;
 7 char str[2*maxn], ss[maxn];
 8 int b[2*maxn];
 9 
10 int main(){
11     int n;
12     scanf("%s",ss);
13     int len = strlen(ss), j = 0, ma = 0, id;
14     for(int i = len; i >= 0; i--){
15         str[2*i+2]=ss[i];
16         str[i*2+1]='#';
17     }
18     str[0]='@';
19     for(int i = 2; i < 2*len+1; i++){
20         if(j+b[j] > i) b[i] = min(b[2*j-i], j+b[j]-i);
21         else b[i] = 1;
22         while(str[i-b[i]] == str[i+b[i]]) b[i]++;
23         if(j+b[j] < i+b[i]) j = i;
24         if(ma < b[i]) ma = b[i], id = j/2;
25     }
26     //printf("%d %d
", id, ma);
27     ma--;
28     id = id - ma/2 + (ma%2 == 0);
29     ss[id+ma-1] = 0;
30     //printf("%d
", id);
31     //printf("%d
",ma);
32     printf("%s
", ss+id-1);
33     return 0;   
34 }

---------------------------------------------------------------

只有不断学习才能进步!

原文地址:https://www.cnblogs.com/wenbao/p/5772411.html