manachar算法小结

1.hdu--4513 吉哥系列故事——完美队形II

http://acm.hdu.edu.cn/showproblem.php?pid=4513

题意:中文题不解释

思路:数字型的manachar算法。将模板中的比较字符改为比较数字就行了。

AC代码:

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 using namespace std;
 7 int a[200005],p[200005],k[200005];
 8 int manachar(int len)
 9 {
10     int maxn,mx,id,i;
11     maxn=mx=id=0;
12     memset(p,0,sizeof(p));
13     for(i=1; i<len; i++)
14     {
15         if(mx>i)
16             p[i]=min(p[id*2-i],mx-i);
17         else
18             p[i]=1;
19         for(; a[i-p[i]]==a[i+p[i]]&&p[i]<=k[i]; p[i]++)
20             if(p[i]+i>mx)
21             {
22                 mx=p[i]+i;
23                 id=i;
24             }
25         if(p[i]>maxn)
26             maxn=p[i];
27     }
28     printf("%d\n",maxn-1);
29     return 0;
30 }
31 int main()
32 {
33     int i,t,n;
34     while(~scanf("%d",&t))
35     {
36         while(t--)
37         {
38             scanf("%d",&n);
39             memset(a,0,sizeof(a));
40             memset(k,0,sizeof(k));
41             a[0]=-1;
42             for(i=0; i<n; i++)
43             {
44                 scanf("%d",&a[i*2+2]);
45                 if(a[i*2+2]>=a[i*2])
46                 {
47                     k[i*2+1]=k[i*2]+1;
48                     k[i*2+2]=k[i*2]+2;
49                 }
50                 else
51                     k[i*2+2]++;
52                 //printf("%d %d\n",i*2+2,k[i*2+2]);
53             }
54             manachar(2*n+2);
55         }
56     }
57     return 0;
58 }

2.hdu--3294 Girls‘ research

http://acm.hdu.edu.cn/showproblem.php?pid=3294

题意:先输入一个字符ch表示该字符的real是‘a’,循环对应的ch-1的real是‘z’,再输入一个字符串,求这个字符串real值的最大回文串,如果有多个结果输出第一个。输出最大回文串的左端点值和右端点值,如果回文串长度是1的话打印“No solution!”

思路:先把给的字符串改成real串,再求最大回文串,并记录real串的左右端点。

AC代码:

 1 #include <iostream>
 2 #include<cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 using namespace std;
 7 char ch,s[200005],str[400005];
 8 int p[400005];
 9 int manachar(int len)
10 {
11     int maxn,mx,id,pi;
12     maxn=mx=id=0;
13     memset(p,0,sizeof(p));
14     for(int i=1;i<len;i++)
15     {
16         if(mx>i)
17             p[i]=min(p[id*2-i],mx-i);
18         else
19             p[i]=1;
20         for(;str[i-p[i]]==str[i+p[i]];p[i]++)
21         {
22             if(p[i]+i>mx)
23             {
24                 mx=p[i]+i;
25                 id=i;
26             }
27         }
28         if(maxn<p[i])
29         {
30             pi=i;
31             maxn=p[i];
32         }
33     }
34     maxn--;
35     if(maxn<3)
36         printf("No solution!\n");
37     else
38     {
39         printf("%d %d\n",(pi-maxn)/2,(pi+maxn-2)/2);
40         for(int i=pi-maxn+1;i<=pi+maxn-1;i=i+2)
41             printf("%c",str[i]);
42         printf("\n");
43     }
44     return 0;
45 }
46 int main()
47 {
48     while(~scanf("%c",&ch))
49     {
50         getchar();
51         gets(s);
52         str[0]=‘$‘,str[1]=‘#‘;
53         int len=strlen(s);
54         for(int i=0;i<len;i++)
55         {
56             if(s[i]>=ch)
57             str[i*2+2]=s[i]-(ch-‘a‘);
58             else
59                 str[i*2+2]=s[i]+26-(ch-‘a‘);
60             str[i*2+3]=‘#‘;
61         }
62         str[len*2+2]=‘\0‘;
63         manachar(len*2+2);
64     }
65     return 0;
66 }

3.hdu--3613 Best Reward

http://acm.hdu.edu.cn/showproblem.php?pid=3613

题意:先输入‘a’~‘z’的价值,然后给出一个字符串,问把这个字符串分成两部分,如果这一部分是回文串则把总价值加上这部分串的价值,求最大的总价值

思路:先把给出的串的总价值进行累加放入数组中,然后对模式串给出的查询串用manachar算法进行计算,如果当前查询到的i<len/2并且p[i]==i时,就max(ans,num[i-1]),如果i>len/2并且p[i]==len-i时,就max(ans,num[n]-num[n-p[i]+1]),如果ans<num[n]在统筹算一下

AC代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 using namespace std;
 7 const int maxn=500005;
 8 char s[maxn],str[maxn<<1];
 9 int num[maxn],k[maxn<<1],p[maxn<<1];
10 int manachar(int len,int n)
11 {
12     int ans,id,mx;
13     id=ans=mx=0;
14     memset(p,0,sizeof(p));
15     memset(k,0,sizeof(k));
16     for(int i=1; i<len; i++)
17     {
18         if(mx>i)
19             p[i]=min(p[id*2-i],mx-i);
20         else
21             p[i]=1;
22         for(; str[i-p[i]]==str[i+p[i]]; p[i]++)
23             if(p[i]+i>mx)
24             {
25                 mx=p[i]+i;
26                 id=i;
27             }
28         if(i<len/2&&p[i]==i)
29         {
30             ans=max(ans,num[i-1]);
31             k[i]=i*2-1;
32         }
33         else if(i>len/2&&p[i]==len-i)
34         {
35             ans=max(ans,num[n]-num[n-p[i]+1]);
36             k[i]=i*2-len+1;
37         }
38     }
39     for(int i=1; i<len/2; i++)
40         if(k[i]==k[len/2+i-1]&&k[i]!=0)
41         {
42             ans=max(ans,num[n]);
43             break;
44         }
45     printf("%d\n",ans);
46     return 0;
47 }
48 int main()
49 {
50     int a[26],t;
51     while(~scanf("%d",&t))
52     {
53         while(t--)
54         {
55             for(int i=0; i<26; i++)
56                 scanf("%d",&a[i]);
57             scanf("%s",s);
58             int len=strlen(s);
59             memset(str,‘#‘,sizeof(str));
60             memset(num,0,sizeof(num));
61             str[0]=‘$‘;
62             for(int i=0; i<len; i++)
63             {
64                 str[i*2+2]=s[i];
65                 num[i+1]=num[i]+a[s[i]-‘a‘];
66             }
67             manachar(len*2+2,len);
68         }
69     }
70     return 0;
71 }

4.poj--3974 Palindrome

http://poj.org/problem?id=3974

题意:给出一系列字符串以“END”结束,问每个字符串的最大回文串的长度

思路:manachar算法直接算。

AC代码:

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 using namespace std;
 7 int p[2000005];
 8 char s[1000005],str[2000005];
 9 int manachar(int len)
10 {
11     int maxn,mx,id,i;
12     maxn=mx=id=0;
13     memset(p,0,sizeof(p));
14     for(i=1; i<len; i++)
15     {
16         if(mx>i)
17             p[i]=min(p[id*2-i],mx-i);
18         else
19             p[i]=1;
20         for(; str[i-p[i]]==str[i+p[i]]; p[i]++)
21             if(p[i]+i>mx)
22             {
23                 mx=p[i]+i;
24                 id=i;
25             }
26         maxn=max(maxn,p[i]);
27     }
28     printf("%d\n",maxn-1);
29     return 0;
30 }
31 int main()
32 {
33     int t;
34     t=1;
35     while(~scanf("%s",s))
36     {
37         if(strcmp(s,"END")==0)
38         break;
39         int len=strlen(s);
40         memset(str,‘#‘,sizeof(str));
41         str[0]=‘$‘;
42         for(int i=0; i<len; i++)
43         {
44             str[i*2+2]=s[i];
45         }
46         str[len*2+2]=‘\0‘;
47         printf("Case %d: ",t++);
48         manachar(len*2+2);
49     }
50     return 0;
51 }

时间: 2024-10-10 21:52:15

manachar算法小结的相关文章

数据挖掘中分类算法小结

数据挖掘中分类算法小结 数据仓库,数据库或者其它信息库中隐藏着许多可以为商业.科研等活动的决策提供所需要的知识.分类与预测是两种数据分析形式,它们可以用来抽取能够描述重要数据集合或预测未来数据趋势的模型.分类方法(Classification)用于预测数据对象的离散类别(Categorical Label);预测方法(Prediction )用于预测数据对象的连续取值. 分类技术在很多领域都有应用,例如可以通过客户分类构造一个分类模型来对银行贷款进行风险评估;当前的市场营销中很重要的一个特点是强

稀疏矩阵的三元组顺序表存储及矩阵相乘算法小结

稀疏矩阵的三元组顺序表存储及矩阵相乘算法小结 巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 一:稀疏矩阵的三元组顺序表数据结构 typedef int ElemType; typedef struct { intx, y;  //该非零元素的行下标和列下标 ElemTypee; //该非零元素的值 } Triple; typedef struct { Tripledata[MAXSIZE]; //非零元素三元组顺序表 intmu, nu, t

hdu 4513 吉哥系列故事——完美队形II (manachar算法)

吉哥系列故事——完美队形II Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Problem Description 吉哥又想出了一个新的完美队形游戏! 假设有n个人按顺序站在他的面前,他们的身高分别是h[1], h[2] ... h[n],吉哥希望从中挑出一些人,让这些人形成一个新的队形,新的队形若满足以下三点要求,则就是新的完美队形: 1.挑出的人保持原队形的相对顺序不变,

18大经典数据挖掘算法小结

18大经典数据挖掘算法小结 本文所有涉及到的数据挖掘代码的都放在了我的github上了. 地址链接: https://github.com/linyiqun/DataMiningAlgorithm 大概花了将近2个月的时间,自己把18大数据挖掘的经典算法进行了学习并且进行了代码实现,涉及到了决策分类,聚类,链接挖掘,关联挖掘,模式挖掘等等方面.也算是对数据挖掘领域的小小入门了吧.下面就做个小小的总结,后面都是我自己相应算法的博文链接,希望能够帮助大家学习. 1.C4.5算法.C4.5算法与ID3

最短路径算法小结

不同性质的图中,所采取的策略有所不同,自然存在各样的求最短路径的算法. 无向无权图:BFS 有向正权图:Dijkstra 有向无负环图:Bellman-Ford(单点),Floyd-Warshall(任意两点) 有向无环图(dags): 基于动态规划的算法. 广度优先搜索(BFS) 对于无向无权图(也可以假设权值为1),就可以使用最基本的广度优先搜索算法,从源点开始对整个图进行搜索,访问到所有的点.因为广度优先搜索最先访问到的是相邻的点,所以距离最近的点最先访问到,记录的距离也就最小. 算法伪代

hdu 3613 Best Reward (manachar算法)

Best Reward Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description After an uphill battle, General Li won a great victory. Now the head of state decide to reward him with honor and treasures for his gr

用HTML5实现的各种排序算法的动画比较 及算法小结

用HTML5实现的各种排序算法的动画比较 http://www.webhek.com/misc/comparison-sort/ 几种排序算法效率的比较 来源:http://blog.chinaunix.net/uid-20773165-id-1847742.html 1.稳定性比较 插入排序.冒泡排序.二叉树排序.二路归并排序及其他线形排序是稳定的 选择排序.希尔排序.快速排序.堆排序是不稳定的 2.时间复杂性比较 插入排序.冒泡排序.选择排序的时间复杂性为O(n2) 其它非线形排序的时间复杂

Paxos算法小结

转自不正直的绅士,因百度空间迁移,无法注明出处,我从其google搜索引擎中的cache进行的copy. 不正直的绅士 是跟我一起工作过的非常有才的一个青年才俊. Paxos的使用非常广泛.sanlock也使用了paxos. 共研究Paxos算法的程序猿参考. Paxos算法小结 1 Paxos算法的背景1.1 State Machine Approach与一致性算法1.2 CAP理论与一致性算法2 Paxos算法2.1 Paxos算法的角色2.2 Paxos算法的描述2.3 Paxos算法的简

Manachar算法详解

求解最长回文串之Manachar算法 问题类型: 输入一个字符串,求出其中最大的回文子串.子串的含义是:在原串中连续出现的字符串片段. 回文的含义是:正着看和倒着看相同,如abba和yyxyy. 这类问题对于一些小数据可以暴力枚举回文的中心点求解(处理好奇数和偶数长度的回文即可) 但是时间复杂度较高 利用manachar算法可以在O(n)时间内得到正确的答案 算法基本要点: 首先用一个非常巧妙的方式,将所有可能的奇数/偶数长度的回文子串都转换成了奇数长度: 在每个字符的两边都插入一个特殊的符号.