问题描述
回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
交换的定义是:交换两个相邻的字符
例如mamad
第一次交换 ad : mamda
第二次交换 md : madma
第三次交换 ma : madam (回文!完美!)
交换的定义是:交换两个相邻的字符
例如mamad
第一次交换 ad : mamda
第二次交换 md : madma
第三次交换 ma : madam (回文!完美!)
输入格式
第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
第二行是一个字符串,长度为N.只包含小写字母
第二行是一个字符串,长度为N.只包含小写字母
输出格式
如果可能,输出最少的交换次数。
否则输出Impossible
否则输出Impossible
样例输入
5
mamad
mamad
样例输出
3
思路:统计各个字符出现次数,出现奇数次的字符最多只能有一个,之后从左往右循环构造回文串
#include<stdio.h>
const int MAXN=8005;
char str[MAXN];
unsigned short ch[26];
int main(){
int n;
int count=0;
scanf("%d",&n);
getchar();
char temp,special;
for(int i=0;i<MAXN;i++){
str[i]=0;
}
for(int i=0;i<26;i++){
ch[i]=0;
}
scanf("%s",str);
for(int i=0;i<n;i++){
ch[str[i]-'a']++;
}
bool flag=false;
for(int i=0;i<26;i++){
if(ch[i]%2){
if(flag){
printf("Impossible\n");
return 0;
}
else{
flag=true;
special=i+'a';
}
}
}
for(int i=0,j=n-1;i<j;i++,j--){
if(str[i]==str[j])
continue;
if(str[i]==special){//特殊字符在左边
int label=i;
for(;label<j;label++){
if(str[label]==str[j])
break;
}
for(int k=label;k>i;k--){
str[k]=str[k-1];
}
str[i]=str[j];
count+=label-i;
}
else{
int label=j;
for(;label>i;label--){
if(str[i]==str[label])
break;
}
for(int k=label;k<j;k++){
str[k]=str[k+1];
}
str[j]=str[i];
count+=j-label;
}
}
printf("%d\n",count);
return 0;
}