蓝桥杯----完美的代价

本文参考:https://blog.csdn.net/qq_40605470/article/details/79268979
这篇文章写的很仔细,看不懂的,可以参考该文。

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

思路分析:
1.先判断输入的字串能否构成回文
2.若不能构成回文,则输出;若能构成回文,则计算最少的交换次数。

  • 算法 :判断能否构成回文

     	若字符串长度为偶数,若存在奇数个数的字符,则不能构成回文;
     	若字符串长度为奇数,若存在两个以上奇数个数的字符,则不能构成回文;
     	综上考虑:若字符长度为偶数,且存在奇数个数的字符,那么奇数个数的字符一定有两个以上。
     	所以判断能否构成回文,直接判断奇数个数字符总数超过两个即可。
    
  • 算法:计算交换次数

     	交换 :只能和相邻的字符交换
     	交换次数最少:每个字符都只能向一个方向移动,从外部向内部移动(保证内部改变不影响外部改变),而且只需要移动一半即可。
    

具体过程

  • 以abbchca字串为例,交换次数为3次。
0123456
abbchca
  • 从左边i=0开始,为a,然后从右边第一个往左查找,右边第一个为a,形成回文;
  • 在左边i=1开始,为b,然后从右边第二个往左查找,第一个与b相等的字符,标记该位置为p=2,然后从p开始往右边第二个位置j=5依次进行交换,并统计次数。
  • 交换过程如下
0123456
abbchca
abcbhca
abchbca
abchcba
  • 一直重复此过程,直到字符串一半的位置,或者已经构成回文结束

  • 另还有一种情况,若存在找不到相等字符的情况;例如:hbabcca,交换次数为6次。

0123456
hbabcca
  • 从左边i=0,为h,找不到相等的字符,直接计算h到中间位置的移动次数,但不用交换;
  • 然后从左边i=1,为b,然后从右边j=6的位置开始向左查找相等字符,然后记住该位置为p=3,然后从p=3位置往j=6的位置进行交换字符,并计算交换次数。
  • 交换过程
0123456
hbabcca
hbacbca
hbaccba
hbaccab
  • 一直重复此过程,直到字符串一半的位置,或者已经构成回文结束。

代码实现

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

void input();//输入 
bool Judje_huiwen(char a[]);//判断是否为回文
void Judje();//判断能否构成回文
void move();//计算移动的次数  

int num[26]={0};//总计字母出现的次数 
char a[8000];//输入字串的长度 
int N;//输入的长度

int main(){
	input();
	Judje();	
} 
void input(){
	cin>>N;
	for(int i=0;i<N;i++){
		cin>>a[i];
	}
} 
bool Judje_huiwen(char a[]){
	char b[N];
	for(int i=N-1,j=0;i>=0;i--,j++){
		b[j]=a[i];
	}
	if(strcmp(a,b)==0){
		return true;
	}
	else{
		return false;
	}
}
void Judje(){
	int sum_odd=0;//字母奇数的个数	
	for(int i=0;i<N;i++){//统计每个字符的个数 
		int temp=a[i];
		num[temp-97]++;
	}
	for(int i=0;i<26;i++){
		if(num[i]%2==1){
			sum_odd++;
		}
	}
	if(sum_odd>=2){//两个以上字母的个数为奇数 
		cout<<"Impossible"<<endl;
	}
	else{
		move();
	}
}
void move(){
	int count=0;//移动的次数 
	int move=0;//最后调整的次数 
	if(Judje_huiwen(a)){//已经是回文 
		cout<<"0"<<endl;
	}
	else{
		int i,j,k;
		int len=N;//len为从右往左开始查找字符匹配的起始位置 
		int l=(N+1)/2;
		for(i=0;i<l;i++){
			for(j=len-1;j>i;j--){
				if(a[i]==a[j]){
				    //交换
					for(k=j;k<len-1;k++){
						a[k]=a[k+1];
						count++; 
					}
					a[len-1]=a[i];
					len--;//找到匹配一次,就从右往左移动一次 
					break;
				}
			}
			if(i==j){//表示该字符未找到匹配的			
				move=l-i-1;
			} 
		}
	}
	cout<<move+count<<endl;	
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值