题目描述:
回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
交换的定义是:交换两个相邻的字符
例如mamad
第一次交换 ad : mamda
第二次交换 md : madma
第三次交换 ma : madam (回文!完美!)
输入:
第一行是一个整数N,表示接下来的字符串的长度(N < = 8000)
第二行是一个字符串,长度为N.只包含小写字母
输出:
如果可能,输出最少的交换次数。
否则输出Impossible
样例输入:
5
mamad
样例输出:
3
解题思路:
1.Impossible
maamdmaam—>奇数个字符出现的次数为1或0时才能实现回文
统计 每个字符出现的次数,如果出现奇数的次数>1时,这时表示不能实现回文;
实现回文交换
mammaaaaadm://可以使用循环交换,也可以使用递归交换(case采用递归交换)
2.从最后面查找第1个出现的位置
3.将一个字符交换到指定的位置
dmama—>mdama
4.奇数个字符的处理
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char arr[8005];
int b[30];
int N,count;
int main(){
//输入
cin>>N;
for(int i=0;i<N;i++){
cin>>arr[i];
b[arr[i]-'a']++;
}
//统计字符串中每个字符出现的次数
//如果字符串中有字符单数的次数>1,表示不可能交换成回文数
for(int i=0,flag=0;i<26;i++){
if(b[i]%2==1){
if(++flag>1){
cout<<"Impossible"<<endl;
return 0;
}
}
}
int start=0,j,flag;
for(int i=0;i<N/2;i++){
flag=0;
for(j=N-i-1;j>i;j--){
if(arr[i]==arr[j]){
for(int start=j;start<N-i-1;start++){
char temp=arr[start];
arr[start]=arr[start+1];
arr[start+1]=temp;
count++;
}
break;//第一次出现相等的时候
}
}
if(j==i){
char temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
count++;
flag=1;
}
if(flag==1){
i--;
}
}
cout<<count<<endl;
}
演示结果
PS:欢迎小伙伴多多交流!!!
后期会继续完善代码及解题思路~~~