回文串是一种特殊的字符串,它从左往右读和从右往左读是一样的,有人认为回文串是一种完美的字符串。现在给你一个字符串,它不一定是回文的,请你计算最少的交换次数使得该字符串变成一个回文串。这里的交换指将字符串中两个相邻的字符互换位置。 例如所给的字符串为”mamad”,第一次交换a和d,得到”mamda”,第二次交换m和d,得到”madma”;第三次交换最后面的m和a,得到”madam”。
输入格式:
第一行是一个整数N(N <= 80),表示所给字符串的长度,第二行是所给的字符串,长度为N且只包含小写英文字母。
输出格式:
如果所给字符串能经过若干次交换变成回文串,则输出所需的最少交换次数;否则,输出Impossible。
输入样例:
5 mamad
结尾无空行
输出样例:
3
结尾无空行
#include<stdio.h>
#include<string.h>
#define MAXN 81
int main(){
int record[26] = {0}; //记录26个小写字母出现次数
int N , len , i , j , count = 0 , left , right , mid , temp , count_exchange = 0 ,flag = 0;
char ch[MAXN];
scanf("%d",&N);
getchar();
gets(ch);
len = strlen(ch);
for(i = 0;i < len;i ++){
record[ch[i] - 'a'] ++;
}
for(i = 0;i < 26;i ++){
if(record[i] % 2== 1){
count ++;
}
}
if(count > 1){ //如果出现奇数次的字符大于1个 ,就不可能构成回文
printf("Impossible");
}else{
left = 0;
right = len - 1;
mid = (left + right) / 2;
for(i = 0;i < len;i ++){
if(record[ch[i] - 'a'] == 1){
flag = 1;
break; //此时i代表出现奇数次字符的下标
}
}
if(flag == 1){
//将i移动到mid位置
if(i > mid){
for(j = i;j > mid;j --){
temp = ch[j];
ch[j] = ch[j - 1];
ch[j - 1] = temp;
count_exchange ++;//记录交换的次数
}
}else if(i < mid){
for(j = i;j < mid;j ++){
temp = ch[j];
ch[j] = ch[j + 1];
ch[j + 1] = temp;
count_exchange ++;
}
}
}
while(left <= right){
if(ch[left] != ch[right]){//若此时left与right不相同
for(i = right - 1;i > left;i --){ //从后往前找到与left相等的字符
if(ch[i] == ch[left]){
break;
}
}
for(j = i;j < right;j ++){
temp = ch[j];
ch[j] = ch[j + 1];
ch[j + 1] = temp;
count_exchange ++;//将找到的字符换到right所在的位置
}
}
left ++;
right --;
}
printf("%d",count_exchange);
}
return 0;
}