问题 1467: [蓝桥杯][基础练习VIP]完美的代价

本文介绍了一种算法,用于计算将任意字符串转换为回文字符串所需的最小字符移动次数。算法首先遍历字符串,寻找可以配对的字符并将其移动到对称位置,同时记录移动次数。此外,还讨论了当字符串长度为偶数或奇数时,构成回文字符串的条件限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

题目大意:计算输入的字符串变为回文字符串所需移动的最少次数;

解题思路:

1.从前向后遍历字符串,对每一个字符找到与该字符相同字符的位置,因为要使得移动次数最少,所以可以从后往前遍历字符串,找到第一个与它相等的字符,并且移动到对称的位置。统计移动的次数;

2.如果字符串长度为偶数,且某个字符的个数为奇数,则说明该字符串不能构成回文字符串;

   如果字符串长度为奇数,且出现两个及两个以上的字符的个数为奇数个,同样也不能构成回文字符串;

参考博客

源码附上:

#include <iostream>
#include <string>
using namespace std;

int main()
{
	int N, sum = 0, k, c = 0, i, j,flag=0;
	cin >> N;
	string s;
	cin >> s;
	int temp = N - 1;

	for (i = 0; i <temp; i++)
	{
		for (j = temp; j > i; j--)
		{
			if (s[i] == s[j])//从前往后找和从后往前找,遇到相等的字母则需要交换位置到合适的地方
			{
				for (k = j; k < temp; k++)
				{
					s[k] = s[k + 1];
				}
				s[temp] = s[i];
				sum += temp - j;//统计移动的次数
				temp--;
				break;
			}
		}
		if (j == i)
		{
			if (N % 2 == 0 || c == 1)//总数为偶数或者之前已有单个字母
			{
				flag = 1;
			}
			else//总数为奇数个,该单个字符并没有移动到中间位置,只是统计了一下要移动的次数
			{
				sum += N/2 - i;
				c = 1;
			}
		}
		if (flag == 1)
		{
			break;
		}
	}
	if (flag == 1)
		cout << "Impossible" << endl;
	else
		cout << sum << endl;
	return 0; 
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值