问题描述
回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。有人认为回文串是一种完美的字符串。现在给你一个字符串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个回文串。这里的交换指将字符串中两个相邻的字符互换位置,例如所给的字符串为mamad,第一次交换ad,得到mamda;第二次交换md,得到madma;第三次交换ma,得到madam (回文!完美!)
程序要求从键盘读入数据。第一行是一个整数N(N <= 8000),表示所给字符串的长度,第二行是所给的字符串,长度为N且只包含小写英文字母。如果所给字符串能经过若干次交换变成回文串,则输出所需的最少交换次数;否则,输出Impossible。
例如:
5
mamad
3
附上代码
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
int MoveStep(char*,int);
string s;
cin>>s;
int len=s.length();
char* p=&s[0];
cout<<MoveStep(p,len)<<endl;
return 0;
}
int MoveStep(char* p,int len)
{
int n=len-1;
int step=0;
int flag=0;
int add_step=0;
for(int i=0;i<n;i++)
{
for(int j=n;j>=0;j--)
{
if(j==i)
{
flag++;
if(flag>1 || n%2==0)//包含了“偶数长度但有一个奇数”
{ //和“奇数长度却有多个奇数”两种情况
cout<<"Impossible"<<endl;
exit(0);
}
add_step+=(len/2-j);//这里是计算奇数放到中间位置所要多少步
break;
}
if(*(p+i)==*(p+j))
{
step+=n-j;
for(int k=j;k<n;k++)
{
*(p+k)=*(p+k+1);
}
*(p+n)=*(p+i);
n--;
break;
}
}
}
return step+add_step;
}