CodeForces 486C Palindrome Transformation(贪心)
题目大意:
将一个不是回文的字符串通过最少的操作使之成为回文串。
操作,左移1位。右移1位,字母+1,字母-1。这些操作到达边界时是有循环的效果的,比如位置到达最后一位往右移动。那么就到达了第一位。
解题思路:
首先须要统计一下有多少个位置是不匹配的,而且将两个不一样的字母通过最少的操作转换成一样的。
然后就是移动位置的计算。
一開始还在想是不是都往一个方向移动好呢。还是移动再返回好呢,或者是移动从后边再返回到前面好呢,后面发现事实上仅仅要每次选取近期的点就能够了。
由于是回文串,位置是对称的。
代码:
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 5;
char str[maxn];
int N, P;
vector<int> pos;
int min (const int a, const int b) {
return a < b ? a: b;
}
int is_palindrome() {
int ans = 0;
int count = 0;
pos.clear();
for (int i = 0; i < N/2; i++) {
if (str[i] != str[N - 1 - i]) {
count++;
int gap = abs(str[i] - str[N - 1 - i]);
// printf ("%d
", gap);
ans += min(gap, 26 - gap);
pos.push_back(abs(i - P) < abs(N - 1 - i - P) ? i + 1 : N - i);
}
}
// printf ("%d%d
", ans, count);
sort(pos.begin(), pos.end());
// printf ("%d %d
", pos[count - 1], pos[0]);
if (ans)
ans += pos[count - 1] - pos[0] + min(abs(pos[0] - P), abs(pos[count - 1] - P));
return ans;
}
int main () {
while (scanf ("%d%d", &N, &P) != EOF) {
scanf ("%s", str);
printf ("%d
", is_palindrome());
}
return 0;
}