蓝桥 BASIC-19 完美的代价

*完美的代价

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

首先,考虑Impossible的情况,当字符串中字母出现次数为奇数的字母数量大于1时,输出Impossible
随后,从左侧首个字母开始进行比较。选中左侧字母后,从右侧首个字母开始比较两个字母是否相同。等到两字母相同时,若字母位置对称则不需交换位置。反之则进行交换,并记录交换次数,以此类推。

若选中奇数字母,则计算其交换至中点位置的距离并记录。
在这里插入图片描述
在这里插入图片描述
最后将两部分交换次数求和并输出

图片来源:https://blog.csdn.net/qq_40605470/article/details/79268979

#include<iostream>
using namespace std;
int main()
{
	int N=0,singular=0,cnt=0;
	int chara[26] = {0};
	cin >> N;
	char s[N] = {0};
	int j=N-1;
	for(int i=0;i<N;i++)
		cin >> s[i];
	for(int i=0;i<N;i++)
		chara[s[i]-'a']++;
	for(int i=0;i<26;i++)
	{
		if(chara[i] % 2 != 0)
			singular++;
	}
	if(singular > 1)
	{
		cout << "Impossible";
		return 0;
	}
	else{
		for(int i=0;i<(N+1)/2;i++)//i-左方指针 
		{
			for(int k=j;k>=i;k--)//k-右方指针 
			{  
				if(s[i]==s[k])
				{
					if(i==k){
						cnt += (N + 1) / 2 - i - 1;
						break;
					}
					while(k<j){
						swap(s[k],s[k+1]);
						cnt++;
						k++;					
					}
					j--;
					break; 
				}
			}	
		}	
	}
	cout << cnt;
	return 0;
}
发布了17 篇原创文章 · 获赞 0 · 访问量 1416

猜你喜欢

转载自blog.csdn.net/weixin_43511030/article/details/104242028