问题描述:回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串
才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美
的回文串。交换的定义是:交换两个相邻的字符,例如 mamad
第一次交换 ad : mamda
第二次交换 md : madma
第三次交换 ma : madam (回文!完美!)
输入格式:第一行是一个整数 N,表示接下来的字符串的长度(N <= 8000)
第二行是一个字符串,长度为 N.只包含小写字母
输出格式:如果可能,输出最少的交换次数。
否则输出 Impossible
样例输入
5
mamad
样例输出
才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美
的回文串。交换的定义是:交换两个相邻的字符,例如 mamad
第一次交换 ad : mamda
第二次交换 md : madma
第三次交换 ma : madam (回文!完美!)
输入格式:第一行是一个整数 N,表示接下来的字符串的长度(N <= 8000)
第二行是一个字符串,长度为 N.只包含小写字母
输出格式:如果可能,输出最少的交换次数。
否则输出 Impossible
样例输入
5
mamad
样例输出
3
//*********************完美的代价
#include <iostream>
#include <string.h>
using namespace std;
int judge(char *c,int n) //judge函数用于判断字符串c是否能构成回文,不能返回-1,能则返回中间字符的信息
{
int count[26]={0},i=0,count_num=0,key=26;
for(i=0;i<n;i++)
count[c[i]-'a']++;
for(i=0;i<26;i++)
if(count[i]%2==1)
{
count_num++;
key=i;
}
if(count_num>1)
key=-1;
return key;
}
void with_center_word(char *c,int n,int key) //with_center_word函数用于计算并显示有中间字符的字符串c构成回文至少需要交换的次数
{
int swap_count=0;
char center_word=(char)(key+'a'); int flag;
for(int i=0;i<n/2;i++)
{
flag=0;
for(int j=n-i-1;j>i;j--)
{
if(c[i]==c[j])
{
for(int y=j;y<n-i-1;y++)
{swap(c[y],c[y+1]); swap_count++;}
flag=1;
break;
}
}
if(flag==0)
{swap(c[i],c[i+1]);swap_count++;i--;}
}
cout << swap_count;
}
void without_center_word(char *c,int n) //without_center_word函数用于计算并显示没有中间字符的字符串c构成回文至少需要交换的次数
{
int swap_count=0;
for(int i=0;i<n/2;i++)
{
for(int j=n-i-1;j>i;j--)
{
if(c[i]==c[j])
{
for(int y=j;y<n-i-1;y++)
{swap(c[y],c[y+1]); swap_count++;}
break;
}
}
}
cout << swap_count;
}
int main()
{
int n;
cin >>n;
if(n>=1&&n<=8000)
{
char *c;
c = new char[n+1];
cin >> c;
if (judge(c,n)==-1) cout << "Impossible";
else if (judge(c,n)==26) without_center_word(c,n);
else with_center_word(c,n,judge(c,n));
delete []c;
}
return 0;
}