【无标题】试题 基础练习 完美的代价

#include <cstring>
#include<iostream>
#include<stdio.h>
using namespace std;

/*
  回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。
  小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,
  请你计算最少的交换次数使得该串变成一个完美的回文串。
  交换的定义是:交换两个相邻的字符
  例如mamad
  第一次交换 ad : mamda
  第二次交换 md : madma
  第三次交换 ma : madam (回文!完美!)

  */


/*
    算法思路
    1 当 N为偶数的时候 如果存在落单的字符无法匹配 匹配失败
    2 当 N为奇数,如果存在超过一个的字符无法匹配,失败
    3 当N为奇数满足条件 此时的做法直接将落单的字符移动到中间,构成回文数
*/

int main() {

    int N, flag=0, sum=0;
    string str;
    cin >> N;
    cin >> str;

    int temp = N - 1;

    for (int i = 0; i < temp; i++)
    {
        for (int j = temp; j >= i; j--)
        {

            if (i == j)
            {
                //已经存在落单的字符 或者 偶数个字符不能有落单的字符
                if (flag || N % 2 == 0) {
                    cout << "Impossible";
                    return 0;
                }
                else
                {
                    flag = 1; // 存在落单字符
                    sum += str.length() / 2 - i; // 加上移动字符到中间次数
                }
            }
            else
            {
                if (str[i] == str[j])//匹配字符成功
                {
                    //移动到对应的位置
                    for (int k = j; k < temp; k++)
                    {
                        swap(str[k], str[k + 1]); 
                        sum++;//记录交换次数
                    }

                    temp--;//尾部前移
                    break;
                }
            }

        }

    }
    //打印输出
    cout << sum << endl;
    
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值