问题描述
回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
交换的定义是:交换两个相邻的字符
例如mamad问题描述
回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
交换的定义是:交换两个相邻的字符
例如mamad
第一次交换 ad : mamda
第二次交换 md : madma
第三次交换 ma : madam (回文!完美!)
第二行是一个字符串,长度为N.只包含小写字母
否则输出Impossible
mamad
交换的定义是:交换两个相邻的字符
例如mamad问题描述
回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
交换的定义是:交换两个相邻的字符
例如mamad
第一次交换 ad : mamda
第二次交换 md : madma
第三次交换 ma : madam (回文!完美!)
输入格式
第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)第二行是一个字符串,长度为N.只包含小写字母
输出格式
如果可能,输出最少的交换次数。否则输出Impossible
样例输入
5mamad
样例输出
3
分析
很明显是使用贪心算法,得到最优解。
步骤:
1、分析什么是退出条件,假设输入为n
1)如果n为奇数,只允许存在一个单数符号;
2)如果n为偶数,不允许存在单数符号;
2、假设当前检索到now(从后开始检索),则步骤为en-now
注意每次匹配完en--。
代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 66666
int main(void){
char a[N];
int s,en,n,m,i,j,now;
int flag=0;
int step=0;
int temp;
memset(a,0,sizeof(a));//初始化
cin>>n;
cin>>a;
en=n-1;
for(s=0;s<=n/2;s++){
now=en;
while(a[s]!=a[now]){
now--;//从后开始匹配字符
}
if(s==now){//说明是单数字符
if(n%2==0||flag>1){
cout<<"Impossible";
return 0;
}
else{
flag++;
step+=n/2-now;
//temp=a[n/2];
//a[n/2]=a[now];
//a[now]=temp;//如果替换的话会出现第8个和第10个过不了。。。
}
continue;
}
else{//说明是双数字符
step+=en-now;
temp=a[now];
for(i=now;i<en;i++){
a[i]=a[i+1];
}
a[en]=temp;
en--;
}
}
cout<<step<<endl;
return 0;BASIC-19
}