Best Reward && Girls' research
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.
InputThe 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: v
1, v
2, ..., v
26 (-100 ≤ v
i ≤ 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 v
1, the value of 'b' is v
2, ..., and so on. The length of the string is no more than 500000.
OutputOutput 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
题意:
给你一条项链,由26个英文字母构成,每一个字符有一个价值,我们要把这个项链切成两部分,如果切成的直线是一个回文字符串那么他的价值就是所有字符价值之和。
但是要注意是要切完之后的那半部分整体是一个回文字符串才可以加上他的价值
这虽然是一个项链,但是你不能转动它,就相当于它就是一条直线不是一个环
题解:
这个就很容易想了,我们可以先用马拉车算法对这个字符串整体处理一下得到一个回文长度数组Len
在预处理一下这个项链的前缀价值
之后就一个for循环对这个字符串的每一位都判断,要知道Len[i]-1就是回文长度,又因为只有子字符串整体回文才加它的价值,所以就可以用if(Len[i + 1] - 1 == i)
来判断一下
当成立的话就要看它是奇数长度还是偶数长度,偶数长度就直接让他的前一半乘与2就可以了,奇数的话再多加中间那个就可以了
我们还要考虑切完之后后边那一部分是不是也是回文,方法一样
代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 #include<queue> 5 #include<algorithm> 6 using namespace std; 7 const int maxn=5e5+10; 8 char str[maxn*2],s[maxn]; 9 int len,Len[maxn*2],val[maxn],v[30]; 10 void init() 11 { 12 memset(str,0,sizeof(str)); 13 int k=0; 14 str[k++]='$'; 15 for(int i=1; i<=len; ++i) 16 { 17 str[k++]='#'; 18 str[k++]=s[i]; 19 } 20 str[k++]='#'; 21 len=k; 22 } 23 void manacher() 24 { 25 Len[0]=0; 26 int sum=0; 27 int id,mx=0; 28 for(int i=1; i<len; ++i) 29 { 30 if(i<mx) Len[i]=min(mx-i,Len[2*id-i]); 31 else Len[i]=1; 32 while(str[i-Len[i]]==str[i+Len[i]]) Len[i]++; 33 if(Len[i]+i>mx) 34 { 35 mx=Len[i]+i; 36 id=i; 37 } 38 } 39 } 40 int main() 41 { 42 int t; 43 scanf("%d",&t); 44 while(t--) 45 { 46 for(int i=0; i<26; ++i) 47 scanf("%d",&v[i]); 48 scanf("%s",s+1); 49 len=strlen(s+1); 50 for(int i=1; i<=len; ++i) 51 { 52 val[i]=val[i-1]+v[s[i]-'a']; 53 } 54 int n=len; 55 init(); 56 manacher(); 57 int ans=0; 58 for(int i = 1; i < n; i++) 59 { 60 int tmp = 0; 61 if(Len[i + 1] - 1 == i) 62 { 63 if(i % 2) 64 { 65 tmp += val[i / 2] * 2 + v[s[(i + 1) / 2] - 'a']; 66 } 67 else 68 { 69 tmp += val[i / 2] * 2; 70 } 71 } 72 if(Len[i + n + 1] - 1 == n - i) //这个i+n+1就是后面那一部分的中点 73 { 74 if((n - i) % 2) 75 { 76 tmp += (val[i + (n - i) / 2] - val[i]) * 2 + v[s[i + (n + 1- i) / 2] - 'a']; 77 } 78 else 79 { 80 tmp += (val[i + (n - i) / 2] - val[i]) * 2; 81 } 82 } 83 ans = max(ans, tmp); 84 } 85 printf("%d\n",ans); 86 } 87 return 0; 88 }
First step: girls will write a long string (only contains lower case) on the paper. For example, "abcde", but 'a' inside is not the real 'a', that means if we define the 'b' is the real 'a', then we can infer that 'c' is the real 'b', 'd' is the real 'c' ……, 'a' is the real 'z'. According to this, string "abcde" changes to "bcdef".
Second step: girls will find out the longest palindromic string in the given string, the length of palindromic string must be equal or more than 2.
InputInput contains multiple cases.
Each case contains two parts, a character and a string, they are separated by one space, the character representing the real 'a' is and the length of the string will not exceed 200000.All input must be lowercase.
If the length of string is len, it is marked from 0 to len-1.OutputPlease execute the operation following the two steps.
If you find one, output the start position and end position of palindromic string in a line, next line output the real palindromic string, or output "No solution!".
If there are several answers available, please choose the string which first appears.Sample Input
b babd a abcd
Sample Output
0 2 aza No solution!
题意:
就是找出来那一部分回文,并输出回文的区间
题解:
我感觉这一道题一直卡我的就是那个区间,我自己举个例子找错了,导致一直过不了
int r = start/2 + sum/2 - 1; //这个start就是最大回文长度的中心(不是原串),sun是回文串长度
int l = r - sum + 1;
上代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 #include<algorithm> 5 #include<set> 6 using namespace std; 7 const int maxn=400005; 8 const int INF=0x3f3f3f3f; 9 const int mod=998244353; 10 char str[maxn],s[maxn]; 11 int len,Len[maxn],start,value[150],sum; 12 void init() 13 { 14 memset(str,0,sizeof(str)); 15 int k=0; 16 str[k++]='$'; 17 for(int i=0; i<len; ++i) 18 str[k++]='#',str[k++]=s[i]; 19 str[k++]='#'; 20 len=k; 21 } 22 int manacher() 23 { 24 int id,mx=0; 25 sum=0; 26 Len[0]=0; 27 for(int i=1; i<len; ++i) 28 { 29 if(i<mx) Len[i]=min(mx-i,Len[2*id-i]); 30 else Len[i]=1; 31 while(str[i-Len[i]]==str[i+Len[i]]) Len[i]++; 32 if(Len[i]+i>mx) 33 { 34 mx=Len[i]+i; 35 id=i; 36 } 37 if(sum<Len[i]) 38 { 39 sum=Len[i]; 40 start=i; 41 } 42 } 43 return --sum; 44 } 45 int main() 46 { 47 char q[5]; 48 //printf("%d %d\n",'a','z');//97 122 49 while(~scanf("%s%s",q,s)) 50 { 51 len=strlen(s); 52 int x = q[0] - 'a'; 53 54 for(int i=0; s[i]; i++) 55 56 { 57 58 int t = s[i] - 'a'; 59 60 s[i] = (t - x + 26)%26 + 'a'; 61 62 } 63 init(); 64 int w=manacher(); 65 //printf("%d\n",w); 66 if(w>=2) 67 { 68 int r = start/2 + sum/2 - 1; //区间错误 69 int l = r - sum + 1; 70 printf("%d %d\n",l,r); 71 for(int i=l; i<=r; ++i) 72 { 73 printf("%c",s[i]); 74 } 75 printf("\n"); 76 } 77 else printf("No solution!\n"); 78 } 79 return 0; 80 }