1. 程式人生 > >[ 10.4 ]CF每日一題系列—— 486C

[ 10.4 ]CF每日一題系列—— 486C

遍歷 調整 spa cost script algo 每日一題 指向 開始

Description:

  給你一個指針,可以左右移動,指向的小寫字母可以,改變,但都是有花費的a - b 和 a - z花費1,指針移動也要花費,一個單位花費1,問你把當前字符串變成回文串的最小化費是多少

Solution:
  真是貪啊,也怪我沒咋理解題意~~

  首先對於字母的調整肯定是有一個最優值得,無法改變的,能改變的就是我們是改變左區間的還是右邊的呢?

  我們可以記錄改變字母的最大區間長度(一半的區間),我們從0遍歷到中間,得到左區間的範圍,如過p在左區間就用這個範圍,否則用右區間的範圍,所以不如直接把p對稱到左區間

  然後求距離分類就好了,註意別忘了一開始直接是回文串的判斷

Code:

  

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define inf (1 << 28)
using namespace std;
const int maxn = 1e5 + 1e2;
char s[maxn];
int main()
{
    int len,p;
    while(~scanf("%d%d",&len,&p))
    {
        scanf("%s",s);
        //左右對稱的!!!
        if(p > len / 2)
            p = len - p;
        else
            p--;

        int ret = 0;
        int first = -1;
        int last = -1;
        for(int i = 0; i < len / 2;++i)
        {
            char a = s[i];
            char b = s[len - 1 - i];
            if(a == b)continue;
            if(first == -1)first = i;
            last = max(last,i);
            if(a < b)swap(a,b);
            int cost = min(a - b,b - a + 26);
            ret += cost;
        }
        if(first == -1 && last == -1)
            ret = 0;
        else if(p <= first)
            ret += last - p;
        else if(p >= last)
            ret += min(p - first,len - p + last);
        else
        {
            ret += last - first;
            ret += min(p - first,last - p);
        }
        printf("%d\n",ret);

    }
    return 0;
}

[ 10.4 ]CF每日一題系列—— 486C