题目链接
解题思路都在下面的AC代码的注释上了,主要是学习这种思维。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ll n,cnt=0;
cin>>n;
string v;
cin>>v;
ll len=v.size()-1;
bool fg=false;//用于判断仅出现1次的字母是否大于1个
for(ll i=0;i<len;i++)
for(ll j=len;j>=i;j--)
{
if(i==j)//此时找到了一个仅出现1次的字母
{
if(v.size()%2==0||fg)//若字符串长度为偶数,或出现1次的字母是否大于1个,则不可能回文
{
cout<<"Impossible"<<endl;
return 0;//直接结束
}
fg=true;//标记为真,下次若再进入这个if语句,说明现1次的字母个数不止1个
cnt+=n/2-i;//将出现1次的字母移到字符串中间需要的步数
break;
}
else
{
if(v[i]==v[j])
{
for(ll k=j;k<len;k++)
{
swap(v[k],v[k+1]);
cnt++;
}//因为i是从字符串的开始找,j是从字符串末尾开始找
//如果找到俩字母相等,把j对应的字母移动到字符串最右端
//并记录步数
//此时俩字母即可对称
len--;//已经实现一对字母的对称,字符串最右端需要减1
break;//防止影响上面刚刚完成的一对字母的对称
}
}
}
cout<<cnt<<endl;
return 0;
}