【蓝桥杯】基础练习 完美的代价

问题描述
  回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
  交换的定义是:交换两个相邻的字符
  例如 m a m a d mamad mamad
  第一次交换 a d ad ad : m a m d a mamda mamda
  第二次交换 m d md md : m a d m a madma madma
  第三次交换 m a ma ma : m a d a m madam madam (回文!完美!)
输入格式
  第一行是一个整数 N N N,表示接下来的字符串的长度( N N N <= 8000 8000 8000)
  第二行是一个字符串,长度为 N N N.只包含小写字母
输出格式
  如果可能,输出最少的交换次数。
  否则输出 I m p o s s i b l e Impossible Impossible
样例输入
5
m a m a d mamad mamad
样例输出
3

个人思路:外层循环从头开始遍历( i = 0 i = 0 i=0 ~ j ( n − 1 ) j (n - 1) j(n1)),内层循环从尾开始遍历到上层循环 i i i( k = j k = j k=j ~ k = i k = i k=i),若是找到相等的数( s [ i ] = = s [ k ] s[i] == s[k] s[i]==s[k]),则将后面的数移到回文数对应位置;如果( i = = k i == k i==k),说明有一个单个的数,则先判断个数如果为偶数,则说明不可能构成回文数,然后标记此次相等,若下一次再次出现 i = = k i == k i==k,则说明不可能构成回文数,因为说明有两个单个的数

/*
*两种情况判断不能形成回文数
* 1. 找到单个的数并且数为偶数个
* 2. 找到两个单个的数
*/
#include <iostream>
using namespace std;
int main() {
	int n;
	string s;
	cin >> n >> s;
	int flag = 0;
	int count = 0;
	int j = n - 1;
	for (int i = 0; i < j; ++i) {
		for (int k = j; k >= i; k--) {
			if (i == k) {
				//有单个的数并且总数为偶数个、或者已经有一个单个的数
				if (n % 2 ==0 || flag) {
					cout << "Impossible";
					return 0;
				}
				//出现单个的数就标记,然后将该数移到中间
				flag = 1;
				count += n/2 - i;
			}
			//找到相等的数,把后面那个数移到回文数对应的位置
			else if(s[i] == s[k]) {
				for (int m = k; m < j; ++m) {
					swap(s[m], s[m + 1]);
					count++;
				}
				j--;
				break;
			}
		}
	}
	cout << count;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值