1-16完美的代价

 

 我的代码 

修修补补半天,而且并没有严格证明出为什么这样是最少交换,凭直觉右边等于左边试了一下,,,如果这题交换是直接交换两个字符,,,算了不想了

#include<iostream>
using namespace std;

int func(char* a, int n){
	//count记录交换次数,flag标记有几个单独的字符,超过一个就不可能
	//如果恰好有一个单独的字符且n为奇,用mid记录其位置,先跳过它,最后移到中间
	int count = 0, flag = 0, mid = -1;
	for(int i = 0; i < n / 2; ++i){
		int j = n - 1 - i + flag;	//让右边跟左边对齐,如果flag为1就错一位对齐
		while(1){
			if(i == j){
				if(n % 2 == 0 || flag){		//n为偶时有单独的字符或n为奇单独字符超过1
					cout << "Impossible";
					return 0;
				}
				else{						//n为奇且出现了第一个单独的字符
					mid = i;				//记录位置,标识+1
					++flag;
					break;
				}
			}
			if(a[i] == a[j]){				//交换
				for(int k = j; k < n - 1 - i + flag; ++k){
					swap(a[k], a[k + 1]);
					++count;
				}
				break;
			}
			--j;
		}
	}
	if(mid != -1){							//把单独的字符移到中间
		for(int k = mid; k < n / 2; ++k){
			swap(a[k], a[k + 1]);
			++count;
		}
	}
	cout << count;
	return 1;
}

int main(){
	int n, count;
	cin >> n;
	char a[n];
	cin >> a;
	func(a, n);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值