时间限制:1.0s | 内存限制:512.0MB |
---|
回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。 交换的定义是:交换两个相邻的字符 例如mamad 第一次交换 ad : mamda 第二次交换 md : madma 第三次交换 ma : madam (回文!完美!)
第一行是一个整数N,表示接下来的字符串的长度(N <= 8000) 第二行是一个字符串,长度为N.只包含小写字母
如果可能,输出最少的交换次数。 否则输出Impossible
5
mamad
3
此题要求判断所输入字符串是否能转换成回文串,不能的话输出"Impossible"即可,若能,则输出该字符串变换成回文串所需相邻字符交换的次数。用贪心的思想即可理解为将字符串后半段与前半段相应字符交换到对应的位置所需要的交换次数,累加即可得到最终答案。
/**
*
* ━━━━━━神兽出没━━━━━━
* ┏┓ ┏┓
* ┏┛┻━━━┛┻┓
* ┃ ┃
* ┃ ━ ┃
* ┃ ┳┛ ┗┳ ┃
* ┃ ┃
* ┃ ┻ ┃
* ┃ ┃
* ┗━┓ ┏━┛Code is far away from bug with the animal protecting
* ┃ ┃ 神兽保佑,代码无bug
* ┃ ┃
* ┃ ┗━━━┓
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛
*
* ━━━━━━感觉萌萌哒━━━━━━
*
*/
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<deque>
#include<map>
#include<iomanip>
#include<queue>
#include<list>
#include<string>
#include<set>
#include<stack>
#include<vector>
typedef long long ll;
using namespace std;
int main()
{
int n;
cin>>n;
string s;
cin>>s;
int j=n-1;
int cnt=0;//保存交换的次数
int flag=0;//判断是否已经有一个单独的字符
for(int i=0;i<j;i++)//i指针从头遍历到倒数第二个字符
{
for(int k=j;k>=i;k--){//k指针从后面往前一直到i寻找和s[i]相同的s[k]
if(k==i){//如果找不到相同的
if(n%2==0||flag==1)//两种情况:偶数长的字符串存在单个字符或者奇数长字符串存在两个单字符
{
cout<<"Impossible";
return 0;
}
flag=1;
cnt+=n/2-i;
}else if(s[k]==s[i])
{
for(int l=k;l<j;l++)//把s[k]上的字符交换到与s[i]对应的n-i-1即j的位置
{
swap(s[l],s[l+1]);
cnt++;//统计交换的次数
}
j--;
break;
}
}
}
cout<<cnt;
return 0;
}