【字符串入门专题1】hdu3613 【一个悲伤的exkmp】
2017-08-11 17:42
351 查看
Best Reward
Problem DescriptionAfter an uphill battle, General Li won a great victory. Now the head of state decide to reward him with honor and treasures for his great exploit.
One of these treasures is a necklace made up of 26 different kinds of gemstones, and the length of the necklace is n. (That is to say: n gemstones are stringed together to constitute this necklace, and each of these gemstones belongs to only one of the 26 kinds.)
In accordance with the classical view, a necklace is valuable if and only if it is a palindrome - the necklace looks the same in either direction. However, the necklace we mentioned above may not a palindrome at the beginning. So the head of state decide to
cut the necklace into two part, and then give both of them to General Li.
All gemstones of the same kind has the same value (may be positive or negative because of their quality - some kinds are beautiful while some others may looks just like normal stones). A necklace that is palindrom has value equal to the sum of its gemstones'
value. while a necklace that is not palindrom has value zero.
Now the problem is: how to cut the given necklace so that the sum of the two necklaces's value is greatest. Output this value.
Input
The first line of input is a single integer T (1 ≤ T ≤ 10) - the number of test cases. The description of these test cases follows.
For each test case, the first line is 26 integers: v1, v2, ..., v26 (-100 ≤ vi ≤ 100, 1 ≤ i ≤ 26), represent the value of gemstones of each kind.
The second line of each test case is a string made up of charactor 'a' to 'z'. representing the necklace. Different charactor representing different kinds of gemstones, and the value of 'a' is v1, the value of 'b' is v2, ..., and so on.
The length of the string is no more than 500000.
Output
Output a single Integer: the maximum value General Li can get from the necklace.
Sample Input
2
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
aba
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
acacac
Sample Output
1
6
题意:这道题的题意真难get到,先输入n,再输入n组样例,每组样例先输入a~z对应的价值,再输入由a~z组成的字符串,要求把字符串二分后,串1是回文串,串2也是回文串,这样最大价值就是串1和串2的价值相加,否则为0
思路:把s1倒置后为s2,用exkmp函数进行扩展,如果s1的前i个字符等于s2的后i个字符,即ex2[l-i] == i 时,说明s1的前i个字符是回文串,判断后l-i个字符串是否为回文串,再用一次exkmp函数就行啦
~~这这这这绝对是一个悲伤的exkmp,由于这道题方法有很多,我在网上找到的exkmp代码就只有一家能看,(为啥我对exkmp这么执着啊。。)略带强迫的我还特地改了代码格式来看,以为get到了方法,自己还让学姐把练习时间加到中午,然后,队友他们饿着肚子等我得到一个wrong answer,之后就是漫长的debug....,结果发现是自己把ex1和ex2的作用搞混了,ex2存的是s2的任意后缀和s1的前缀最大公共长度,我们通过判断ex2[l-i]==i
来说明s1的前i个字符等于s2的后i个字符,进而说明串的前i个字符为回文串。ex1存的是s1的任意后缀和s2的前缀最长公共长度,我们通过判断ex1[i] == l-i 来说明s1的后l-i个字符等于s2的前l-i个字符,进而说明串的后l-i个字符是回文串。
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; #define N 550000 char s1 ,s2 ; int ex1 ,ex2 ,v ; int b1 ,b2 ; int s[27]; int t; void exkmp(char s1[],char s2[],int next[],int ex[]) { int i,j,p; i = j = 0; p = -1; while(s1[i]!='\0') { if(p == -1) { j = 0; do p++; while(s1[i+p]!='\0'&&s1[i+p]==s2[j+p]); ex[i] = p; } else if(next[j]>p) ex[i] = p; else if(next[j]<p) ex[i] = next[j]; else { j = 0; while(s1[i+p]!='\0'&&s2[j+p] == s1[i+p]) p++; ex[i] = p; } i++; j++; p--; } ex[i] = 0; return; } int main() { int i,j,sum,ans,l; scanf("%d",&t); while(t --) { getchar(); memset(v,0,sizeof(v)); memset(b1,0,sizeof(b1)); memset(b2,0,sizeof(b2)); for(i = 0; i < 26; i ++) cin>>s[i]; scanf("%s",s1); l = strlen(s1); for(i = 1; i <= l; i ++) { v[i] = v[i-1]+ s[s1[i-1]-'a']; s2[i-1] = s1[l-i]; } exkmp(s2+1,s2,b1,b1+1);//调用一次exkmp函数计算s2的next数组 exkmp(s1,s2,b1,ex1);//再次调用exkmp函数计算s1的任意后缀和s2前缀最长公共长度的ex1数组 exkmp(s1+1,s1,b2,b2+1);//调用函数计算s1的next数组 exkmp(s2,s1,b2,ex2);//计算s2的任意后缀和s1的前缀最长公共长度的ex2数组 ans = sum = 0; for(i = 1; i < l; i ++) { if(ex2[l-i] == i)//串的前i个字符是回文串 sum += v[i]; if(ex1[i] == l-i)//串的后l-i个字符是回文串 sum += v[l] - v[i]; if(sum > ans ) ans = sum; sum = 0; } printf("%d\n",ans); } return 0; }
d2e6
相关文章推荐
- 【字符串入门专题1】F - Seek the Name, Seek the Fame poj2752【kmp】
- tarjan算法入门整理专题(判断是否是一个强连通、通过缩点求至少加几条边让整个图变成强连通和传递的最小费用)
- mybatis学习-入门(4)-一个完整的web例子,通过json将字符串传递给前台,然后显示出来
- 【字符串入门专题1】 E - Cyclic Nacklace hdu3764 【kmp最小循环节应用】
- 一个专题让你轻松入门机器学习
- 【字符串入门专题1】 I - Number Sequence hdu1711【kmp】
- C#新手入门代码 将一个string字符串转换成char数组
- 正则入门:匹配零个或一个字符串
- 【字符串入门专题1】C - A + B for you again hdu1867【kmp】
- c++入门:输入一个字符串,将其分段输出,分段符为除字母和数字之外的符号。
- 【字符串入门专题1】A - 亲和串 hdu 2203 【kmp】
- Redis资料汇总专题:说NoSQLFan上的资料不少,但是要找到自己实用的太难,于是萌生做这样一个专题的想法。通过将不同NoSQL产品从入门到精通的各种资料进行汇总
- 【字符串入门专题1】J - Oulipo hdu1686 【kmp】
- 【字符串入门专题1】【hdu4763】【未ac题】【扩展kmp exkmp】
- [C#新手入门十] 如何判断一个字符串中值不包含字母,数字和“_”
- 【字符串入门专题1】D - Period hdu 1358【kmp-最小循环节简单应用】
- 查找一个字符串里,出现次数最多的字符,时间复杂度O(n)
- Python入门二(一个有趣的画图例子)
- 一句话将表的一列数据叠成一个字符串
- (1)写一个程序,用于分析一个字符串中各个单词出现的频率,并将单词和它出现的频率输出显示。(单词之间用空格隔开,如“Hello World My First Unit Test”); (2)编写单元测试进行测试; (3)用ElcEmma查看代码覆盖率,要求覆盖率达到100%。