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\n", 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("\n");
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\n", id, ma);
27     ma--;
28     id = id - ma/2 + (ma%2 == 0);
29     ss[id+ma-1] = 0;
30     //printf("%d\n", id);
31     //printf("%d\n",ma);
32     printf("%s\n", ss+id-1);
33     return 0;
34 }

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

只有不断学习才能进步!

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

时间: 2024-10-19 20:30:51

wenbao与manacher的相关文章

BZOJ 2084 [Poi2010]Antisymmetry(manacher)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2084 [题目大意] 对于一个01字符串,如果将这个字符串0和1取反后, 再将整个串反过来和原串一样,就称作“反对称”字符串. 比如00001111和010101就是反对称的,1001就不是. 现在给出一个长度为N的01字符串,求它有多少个子串是反对称的. [题解] 修改manacher的判定条件,对该串进行计算即可. [代码] #include <cstdio> #include

HDU 3068 最长回文 (manacher算法)

最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9188    Accepted Submission(s): 3159 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组

manacher马拉车算法

入门manacher最好文章:https://segmentfault.com/a/1190000003914228 我整理了模板代码:HDOJ3068马拉车模板 1 //讲解 https://segmentfault.com/a/1190000003914228 2 //manacher 算法模板 3 //求最长回文串 O(N) 4 #include <bits/stdc++.h> 5 using namespace std; 6 const int maxn=3e5+10; 7 char

HDU 4513 吉哥系列故事——完美队形II (Manacher变形)

题意:假设有n个人按顺序的身高分别是h[1], h[2] ... h[n],从中挑出一些人形成一个新的队形,新的队形若满足以下要求,则就是新的完美队形:  1.连续的 2.形成回文串 3.从左到中间那个人,身高需保证不下降 问有组成完美队形的最多人数 题解:Manacher算法的变形. 首先我们来解释一下Manacher算法:在我看来就是一个优化的暴力. 我们首先统一奇偶回文串成为奇数回文串,就是在两个数之间加入一些不可能出现的数. 例如题目:1 2 3 3 2 5 2 3 1—>(符号更加清楚

hdu5785--Interesting(manacher)

题意:求给定字符串的三元组(I,J,K)  使得S[i..j] 和 S[j+1..k] 都是回文串.求所有满足条件的三元组 ∑(i*k) 题解:求出以j为结尾的回文串起始位置的和记为lv[j],和以j+1为开始的回文串末位置的和rv[j+1] 答案就是∑[j:1-n](lv[j] * rv[j+1]) 因为…… (a+b+c....)*(x+y+z.....) = a*x + a*y + a*z + .... 看了题解之后才恍然大悟ˊ_>ˋ有多蠢 然后就是自己写的代码 一直wa,以为哪里没有取模

HDU5677 manacher + 二维多重背包

附上题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5677 问题描述 ztr喜欢研究子串,今天,他有n个串 现在ztr想知道,能否从这n个串的所有回文子串中, 取出恰好k个回文串且满足这些回文串的长度之和为L 以yjqqaq为例 这个串包含的回文子串有 y,j,q,a,q,qq,qaq 所以我们可以既选qq,又选qaq 输入描述 有T组数据,第一行为一个正整数T(T<=10)T(T<=10) 每组数据第一行为三个正整数N(1<=N<

HDU3068 manacher算法

附上题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068  这个题的意思是给你一个串, 求这个串中的最长的回文串的长度, 直接裸manacher即可. 代码如下: #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; const int maxn = 110000*2

manacher算法模板

char a[maxn]; int p[maxn]; //manacher void manacher(char *s){ int len = strlen(s+1); int m = 2*len+1; for(int i=1; i<=len; i++){ a[i<<1] = s[i]; a[i<<1|1] = '#'; } a[0] = '+'; a[1] = '#'; a[m+1] = '-'; // cout<<a<<endl; int mx=0

Girls&#39; research(manacher)

Girls' research Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 1160    Accepted Submission(s): 448 Problem Description One day, sailormoon girls are so delighted that they intend to research a