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 ",ret); } return 0; }