蓝桥杯基础练习 完美的代价

问题描述

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

输入格式

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

输出格式

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

样例输入

5
mamad

样例输出

3

解题思路:

求最少的交换次数,考虑用贪心算法,当一个字符不动,另一个字符移动到对称位置时移动步数最少。

有字符个数为奇数和偶数两种情况:

  1. 字符个数为偶数,不能有不对称的字符。
  2. 字符个数为奇数,没有对称字符的字符只能有一个,设变量flag来标记是不是第一次不对称。

另外需要注意:

  奇数情况下若找到不对称字符,不能先移动它,将移动至中间所需要的步数加入总步数即可,可以想象第一个字符为非对称字符的情况代入程序中,非对称字符移动到中间,使得第二个字符变成第一个字符,但是外循环已经跳过了第一个字符(如果要先移动非对称字符,则移动后需要从上一个位置重新计算)。

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

int main()
{
    char str[8001];
    int n, end, j, k, cnt=0, flag=1;
    cin>>n;getchar();
    for(int i=0; i<n; i++)
        scanf("%c", &str[i]);
    end = n-1;    //end为最后一个字符下标
    //从头开始遍历
    for(int i=0; i<end; i++)
    {
        //从末尾开始遍历
        for(j=end; j>=i; j--)
        {
            //找不到相同的字符
            if(i == j)
            {
                //判断不是第一次找不到匹配的字符 或 n为偶数
                if(flag==0 || n%2==0)
                {
                    //返回impossible
                    printf("Impossible\n");
                    return 0;
                }
                //是第一次找不到且n为奇数,则将flag变为0,计算应该移动多少位(n/2-j)但不要真的移动
                /*
                *不匹配的字符如果在数组的后半部分则当其他位置匹配时必然n/2==j,
                *即不需要移动,如果在前半部分则需要移动n/2-j,当然减i也行(此时i==j)
                */
                else
                {
                    flag = 0;
                    cnt += n/2-i;
                }
            }
            //找到相同的字符
            else if(str[j] == str[i])
            {
                //将该位置的字符与向后相邻的字符交换,直到end
                for(k=j; k<end; k++)//注意不能连end也算入,k+1已经替换了end
                {
                    swap(str[k], str[k+1]);
                    cnt++;
                }
                //end向前移动一位(因为该位置已经对称)
                end--;
                break;
            }

        }
    }
    cout<<cnt<<endl; 

    return 0;
}

/*注:
程序中的判断是否找到相同字符if... else if...位置不可交换,因为i==j时,
必然str[i]==str[j],但是这是找不到的情况
*/

原文地址:https://www.cnblogs.com/kamicoder/p/8535214.html

时间: 2024-10-03 14:41:56

蓝桥杯基础练习 完美的代价的相关文章

蓝桥杯 基础练习 BASIC-19 完美的代价

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

蓝桥杯——基础练习之分治法_快速排序

分治法,分而治之,基本思路:分,解,和. 初探分治之快速排序. public class _DividedConquer { static int[] iarr; public static void main(String[] args) { // TODO Auto-generated method stub iarr=new int[]{6,4,5,3,1,2}; quick(0, iarr.length-1); for(int i:iarr) { System.out.print(i+"

蓝桥杯——基础练习之FJ的字符串

问题描述 FJ在沙盘上写了这样一些字符串: A1 = "A" A2 = "ABA" A3 = "ABACABA" A4 = "ABACABADABACABA" - - 你能找出其中的规律并写所有的数列AN吗? 输入格式 仅有一个数:N ≤ 26. 输出格式 请输出相应的字符串AN,以一个换行符结束.输出中不得含有多余的空格或换行.回车符. 样例输入 3 样例输出 ABACABA public static void main(

蓝桥杯—— 基础练习之Sine之舞

问题描述 最近FJ为他的奶牛们开设了数学分析课,FJ知道若要学好这门课,必须有一个好的三角函数基本功.所以他准备和奶牛们做一个"Sine之舞"的游戏,寓教于乐,提高奶牛们的计算能力. 不妨设 An=sin(1–sin(2+sin(3–sin(4+...sin(n))...) Sn=(...(A1+n)A2+n-1)A3+...+2)An+1 FJ想让奶牛们计算Sn的值,请你帮助FJ打印出Sn的完整表达式,以方便奶牛们做题. 输入格式 仅有一个数:N<201. 输出格式 请输出相应

蓝桥杯-基础练习-十六进制转八进制(被超时了!!!)

基础练习 十六进制转八进制 时间限制:1.0s   内存限制:512.0MB 问题描述 给定n个十六进制正整数,输出它们对应的八进制数. 输入格式 输入的第一行为一个正整数n (1<=n<=10). 接下来n行,每行一个由0~9.大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000. 输出格式 输出n行,每行为输入对应的八进制正整数. 注意 输入的十六进制数不会有前导0,比如012A. 输出的八进制数也不能有前导0. 样例输入 2 39 123ABC 样

蓝桥杯练习系统—基础练习 完美的代价

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

蓝桥杯 基础练习 BASIC-12 十六进制转八进制

基础练习 十六进制转八进制 时间限制:1.0s   内存限制:512.0MB 问题描述 给定n个十六进制正整数,输出它们对应的八进制数. 输入格式 输入的第一行为一个正整数n (1<=n<=10). 接下来n行,每行一个由0~9.大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000. 输出格式 输出n行,每行为输入对应的八进制正整数. [注意] 输入的十六进制数不会有前导0,比如012A. 输出的八进制数也不能有前导0. 样例输入 2 39 123ABC

蓝桥杯 基础练习 十六进制转八进制 【字符串处理】

  基础练习 十六进制转八进制   时间限制:1.0s   内存限制:512.0MB      问题描述 给定n个十六进制正整数,输出它们对应的八进制数. 输入格式 输入的第一行为一个正整数n (1<=n<=10). 接下来n行,每行一个由0~9.大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000. 输出格式 输出n行,每行为输入对应的八进制正整数. 注意 输入的十六进制数不会有前导0,比如012A. 输出的八进制数也不能有前导0. 样例输入 2 39

基础练习 完美的代价

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