Codefroces 486C Palindrome Transformation【贪心】好题

来源:互联网 发布:sql查询分析器在哪里 编辑:程序博客网 时间:2024/05/21 10:02

C. Palindrome Transformation
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Nam is playing with a string on his computer. The string consists of n lowercase English letters. It is meaningless, so Nam decided to make the string more beautiful, that is to make it be a palindrome by using 4 arrow keys: left, right, up, down.

There is a cursor pointing at some symbol of the string. Suppose that cursor is at positioni (1 ≤ i ≤ n, the string uses 1-based indexing) now. Left and right arrow keys are used to move cursor around the string. The string is cyclic, that means that when Nam presses left arrow key, the cursor will move to position i - 1 ifi > 1 or to the end of the string (i. e. positionn) otherwise. The same holds when he presses the right arrow key (ifi = n, the cursor appears at the beginning of the string).

When Nam presses up arrow key, the letter which the text cursor is pointing to will change to the next letter in English alphabet (assuming that alphabet is also cyclic, i. e. after 'z' follows 'a'). The same holds when he presses the down arrow key.

Initially, the text cursor is at position p.

Because Nam has a lot homework to do, he wants to complete this as fast as possible. Can you help him by calculating the minimum number of arrow keys presses to make the string to be a palindrome?

Input

The first line contains two space-separated integers n (1 ≤ n ≤ 105) andp (1 ≤ p ≤ n), the length of Nam's string and the initial position of the text cursor.

The next line contains n lowercase characters of Nam's string.

Output

Print the minimum number of presses needed to change string into a palindrome.

Examples
Input
8 3aeabcaez
Output
6
Note

A string is a palindrome if it reads the same forward or reversed.

In the sample test, initial Nam's string is: (cursor position is shown bold).

In optimal solution, Nam may do 6 following steps:

The result, , is now a palindrome.


题目大意:

给你一个长度为N的字符串,初始指针位于位子p,一共有四种操作:

①指针向左移动

②指针向右移动

③指针位子的字符字典序+1(仅限于a-z)z+1=a

④指针位子的字符字典序-1(仅限于a-z)a-1=z

问最少操作多少次,能够使得整个字符串是一个回文的。


思路:


1、首先考虑这样一个问题,如果我们想要将整个字符串变成一个回文串,其实相当于我们将左边一半或者右边一半的字符串使得变成和另外一半镜像的存在即可。

那么我们将字符串分成两部分:【1,n/2】【n/2,n】;


2、那么如果我们现在的指针p位于左半边,那么我们就考虑将左半部分变成和有半部分镜像即可,同理,如果我们现在的指针p位于右半边,那么我们就考虑将右半部分变得和左半部分镜像即可。相当于,无论指针p位于左半边还是右半边,我们都需要将一半的字符串变成另一半字符串的镜像,辣么我们直接一层for扫一半的字符串,如果其和对应的镜像位子的字符不同,那么output+=min(使得两个字符相同的字典序向上的操作次数,使得两个字符相同的字典序向下的操作次数);


3、那么接下来考虑指针如何移动的问题。如果我们指针当前在左半边,那么明显我们只需要指针在左半边移动即可,同理,如果我们指针在右半边,那么明显我们只需要在右半边移动即可。


4、那么我们对应在指针所在的半边中,找到需要改变的第一个字符的位子记做l,找到需要改变的最后一个字符的位子记做r,那么我们指针就只需要在【l,r】这部分移动即可。那么如果p<=l,那么output+=r-p;那么如果p>=r,那么output+=p-l,那么如果p位于【l,r】之间,那么我们很容易贪心:output+=(r-l)+min(p-l,r-p);


5、处理完所有程序,输出output即可。


Ac代码:

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>using namespace std;char a[1000400];int main(){    int n,p;    while(~scanf("%d%d",&n,&p))    {        scanf("%s",a+1);        int mid=n/2;        int l=-1,r=-1;        int cont=0;        int output=0;        if(p<=mid)        {            for(int i=1; i<=mid; i++)            {                if(a[i]!=a[n-i+1])                {                    cont++;                    int tmp=abs(a[i]-a[n-i+1]);                    tmp=min(tmp,26-tmp);                    output+=tmp;                    if(l==-1)l=i;                    r=i;                }            }        }        else        {            for(int i=mid+1; i<=n; i++)            {                if(a[i]!=a[n-i+1])                {                    int tmp=abs(a[i]-a[n-i+1]);                    tmp=min(tmp,26-tmp);                    output+=tmp;                    cont++;                    if(l==-1)l=i;                    r=i;                }            }        }        if(cont==0)        {            printf("0\n");            continue;        }        output+=r-l;        if(p<=r&&p>=l)output+=min(abs(p-r),abs(p-l));        else        {            if(p<=l)output+=l-p;            if(p>=r)output+=p-r;        }        printf("%d\n",output);    }}


0 0