参考:
https://blog.csdn.net/liuchuo/article/details/51990430
分析:过程见代码注释部分。其中有两个注意点:
1.impossible的情况:如果有一个字符出现的次数是奇数次数,而且n是偶数,那么不可能构成回文
如果n是奇数,但是已经有一个字符出现的次数是奇数次数了,那么如果又有一个字符是奇数次数,就不可能构成回文。
2.如果n是奇数,计算中间那个字符交换的次数的时候,不需要模拟把这个数移动到中间去,因为移动到中间的话假设有一对数都在左边或者都在右边,那么交换成回文的时候就要经过中间,就会每次把cnt多加了1,而这个1是没有必要的,因为可以所有的回文移动完了之后再把这个独立的奇数移动过去,才能保证交换次数最少。
————————————————
版权声明:本文为CSDN博主「柳婼」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/liuchuo/article/details/51990430
代码:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
string str = "";
int n;
cin>>n;
cin>>str;
int res = 0;
int left = 0,right = n - 1;
bool flag = false;
while(left < right)
{
for(int k = right; k >= left; k--)
{
if(k == left)//str[left]只有奇数个
{
if( n % 2 == 0 || flag == true)
{//n位偶数时不能有奇数个的字符,n为奇数时不能有两个奇数个的字符
cout<<"Impossible";
return 0;
}
flag = true;
res += n/2 - left; //把str[left]移动到最中间,但先在先不移
left++; //只让left右移,right不动
}
else if(str[k] == str[left])
{//找到了
for(int t = k; t < right; t++)
{//交换
swap(str[t],str[t+1]);
res++;
}
left++;
right--;
break;
}
}
}
cout<<res;
return 0;
}