2015 HIAST Collegiate Programming Contest C

Palindrome Again !!

题意:将一个长度为n的字符串改成一个回文,但是修改是有代价的,开始有一个p,表示p指向的字符的位置,每次修改只能修改p所指向的字符,修改的代价为a->b为1,c->a为2,a-z为1,y->a为2,以此类推,并且p可以左右移动,每移动一个位置代价为1,求最少的代价使字符串变成回文

思路:因为字符之间相互转化的代价是一样的,如 a-g 与g-a的代价是一样的,所以,以n-1>>1 位置的一个或者2个字符作为中点,只需要改变某一边就可以了,和和改变另一边的代价是等价的,如果p的初始位置不在改变的一遍,则只需将p的位置换到另一边对应的位置就可以了,每次需要记录p所需要到的最左边和最右边的位置lm和rm,用于计算改变p的位置所花的代价,最后计算p所花代价的时候需要注意分类讨论,将lm和rm与p的位置关系作为分类讨论的点

AC代码:

#include "iostream"
#include "string.h"
#include "stack"
#include "queue"
#include "string"
#include "vector"
#include "set"
#include "map"
#include "algorithm"
#include "stdio.h"
#include "math.h"
#define ll long long
#define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
#define mem(a) memset(a,0,sizeof(a))
#define mp(x,y) make_pair(x,y)
using namespace std;
const long long INF = 1e18+1LL;
const int inf = 1e9+1e8;
const int N=1e5+100;

///2015 HIAST Collegiate Programming Contest

char a[N];
int n,p;
int change_cost(int i){
    char ch=a[i];
    int k1=0, k2=0;
    for(int j=1; j<=60; ++j){
        k1=j;
        ch++;
        if(ch>'z') ch='a';
        if(ch==a[n-i+1]) break;
    }
    ch=a[i];
    for(int j=1; j<=60; ++j){
        k2=j;
        ch--;
        if(ch<'a') ch='z';
        if(ch==a[n-i+1]) break;
    }
    return min(k1,k2);
}
int main(){
    int t;
    cin>>t;
    while(t--){
        cin>>n>>p>>a+1;
        int mid=n+1>>1;
        int lm=inf,rm=-inf;
        ll ans=0;
        for(int i=1; i<=mid; ++i){
            if(a[i]!=a[n-i+1]){
                lm=min(lm,i);
                rm=max(rm,i);
                ans+=change_cost(i);
            }
        }//cout<<lm<<" "<<rm<<endl;
        if(lm>rm){
            cout<<0<<endl;
            continue;
        }
        if(p>mid) p=n-p+1;
        if(rm<=p && lm<=p){
            ans+=abs(p-lm);
        }
        else if(rm>p && lm>p){
            ans+=abs(p-rm);
        }
        else{
            int step_l=abs(p-lm), step_r=abs(p-rm);
            ans+=2*min(step_l,step_r)+max(step_l,step_r);
        }
        cout<<ans<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/max88888888/p/7161766.html