题目
完美的代价
描述
回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
交换的定义是:交换两个相邻的字符
例如mamad
第一次交换 ad : mamda
第二次交换 md : madma
第三次交换 ma : madam (回文!完美!)
输入描述:
第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
第二行是一个字符串,长度为N.只包含小写字母
输出描述:
如果可能,输出最少的交换次数。
否则输出Impossible
输入样例:
5
mamad
输出样例:
3
下面是本人所写代码,大致思路是通过交换先解决字符串两边,再解决中间:
#include <stdio.h>
//以下先声明一个交换函数,每次交换相邻数组,交换次数(stp)+1
void swpt(char* a,char* b,int* stp)
{
char* temp;
temp = a;
a = b;
b = temp;
*stp++;
}
int main()
{
int len;//声明数组长度
scanf("%d",&len);//从键盘读取数组长度
char a[len];//声明字符串数组
scanf("%s",&a);//从键盘读取字符串数组
int k=len-1,stp=0,non_match=0;//初始化未解决范围k,交换次数stp ,不存在匹配的字母数 non_match
for(int i=0;i<=k;i++)//从左开始遍历需要配对的 a【i】
{
for(int j=k;j>=i;j--)// 从右开始遍历寻找与a【i】 配对的 a【j】
{
if(a[i]==a[j]&&i!=j)//如果找到
{
for(int x=j;x<=k-1;x++)//将a【j】移动至未解决范围内最左端
{
swpt(a+x,a+x+1,&stp);
}
k--;//缩小未解决范围
}
else if(a[i]==a[j]&&i==j)//如果未找到,a【i】则为不存在匹配的字母
{
if(i<=(len-1)/2)//a【i】偏左,移动至中间
{
for(int x=i;x<=(len-1)/2-1;x++)
{
swpt(a+x,a+x+1,&stp);
}
non_match++;
}
else// a【i】偏右,移动至中间
{
for(int x=i;x>=(len-1)/2+1;x--)
{
swpt(a+x,a+x-1,&stp);
}
non_match++;
}
}
}
}
//讨论输出结果
if(non_match>1) printf("Impossible");//如果不存在匹配的字母数大于1,无论奇偶,都不可能是回文串
else if(non_match==1)// 如果存在一个不存在匹配的字母
{
if(len%2==0) printf("Impossible");//如果长度为偶数,不可能是回文串
else printf("%d",stp);//如果长度为奇数,输出交换次数
}
else //如果没有不存在匹配的字母
{
if(len%2==1) printf("Impossible");//如果长度为奇数,不可能是回文串
else printf("%d",stp);//如果长度为偶数,输出交换次数
}
return 0;
}
输入测试:
5
mamad
输出测试:
Impossible
显然代码存在错误
请依据本人的代码寻找错误并修改或改进,请不要重写代码,谢谢!