蓝桥杯———完美的代价(贪心算法)

基础练习 完美的代价  

时间限制:1.0s   内存限制:512.0MB

      

问题描述

  回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
  交换的定义是:交换两个相邻的字符
  例如mamad
  第一次交换 ad : mamda
  第二次交换 md : madma
  第三次交换 ma : madam (回文!完美!)

输入格式

  第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
  第二行是一个字符串,长度为N.只包含小写字母

输出格式

  如果可能,输出最少的交换次数。
  否则输出Impossible

样例输入

5
mamad

样例输出

3

思路:左侧第i个字符对应右侧 n-i-1个字符,如果str[i] != str[n-i-1] ,就分别计算从i开始向右寻找到等于str[n-i-1]所花费的步数和从n-i-1开始向左寻找等于str[i]所花费的步数,采取较小步数的方案,循环下去,直到 i等于中间字符。

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn = 8001;
const int inf = INT_MAX;
int main(){
	int n;
	char str[maxn];
	scanf("%d",&n);
	getchar();
	for(int i = 0;i < n;i++)
		scanf("%c",str + i);
	getchar();

	int step = 0;
	for(int i = 0;i <=n/2;i++){
		if(str[i]==str[n-i-1])
			continue;
		else{
			int judge = 1;
			int stepl = inf;
			int stepr = inf;
			int l=i+1,r = n-i-2;
			while(str[l]!= str[n-i-1] && l <n-i-1 )
				l++;
			if(str[l] == str[n-i-1]){
				judge = 0;
				stepl = l - i;
			}
		
			while(str[r]!= str[i] && r > i)
				r--;
			if(str[r] == str[i]){
				judge = 0;
				stepr = n-i-1-r;
			}
			if(judge){
				cout<<"Impossible"<<endl;
				return 0;
			}else if(stepl < stepr){
				while(l > i){
					swap(str[l],str[l-1]);
					l--;
				} 
				step +=stepl;
			}else{
				while(r < n-i-1){
					swap(str[r],str[r+1]);
					r++;
				}
				step+=stepr;
			}
		
		}
	}
	cout<<step<<endl;
	
}

猜你喜欢

转载自blog.csdn.net/curtern/article/details/88124452