LQ0149 排序枚举

Posted 海岛Blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LQ0149 排序枚举相关的知识,希望对你有一定的参考价值。

题目来源:蓝桥杯2020初赛 Java B组E题

题目描述
小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。
在冒泡排序中,每次只能交换相邻的两个元素。
小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符,则在所有可能的排序方案中,冒泡排序的总交换次数是最少的。
例如,对于字符串lan 排序,只需要1 次交换。对于字符串qiao 排序,总共需要4 次交换。
小蓝找到了很多字符串试图排序,他恰巧碰到一个字符串,需要100 次交换,可是他忘了吧这个字符串记下来,现在找不到了。
请帮助小蓝找一个只包含小写英文字母且没有字母重复出现的字符串,对该串的字符排序,正好需要100 次交换。如果可能找到多个,请告诉小蓝最短的那个。如果最短的仍然有多个,请告诉小蓝字典序最小的那个。

这是一道结果填空的题,你只需要算出结果后提交即可。
本题的结果为一个只包含小写英文字母的字符串,在提交答案时只填写这个字符串,填写多余的内容将无法得分。

问题分析
根据冒泡排序的交换字数进行计算,先算出需要的字符串长度。先考虑最多交换次数,再做调整。

AC的C语言程序如下:

/* LQ0149 排序 */

#include <stdio.h>

#define N 100

int main()

    /* 计算字符串最短长度, n个字母完全逆序需要交换n(n-1)/2次 */
    int n = 1;
    while (n * (n - 1) / 2 < N)
        n++;

    char s[20];
    for (int i = 0; i < n; i++)
        s[i] = 'a' + n - 1 - i;
    s[n] = '\\0';

    /* 计算差额 */
    int m = n * (n - 1) / 2 - N;
    /* 调整差额 */
    for (int i = m; i > 0; i--)
        if (s[i] < s[i - 1]) 
            char t = s[i];
            s[i] = s[i - 1];
            s[i - 1] = t;
        

    printf("%s\\n", s);

    return 0;

以上是关于LQ0149 排序枚举的主要内容,如果未能解决你的问题,请参考以下文章

LQ0018 顺子日期枚举+日期

LQ0020 加法变乘法枚举

LQ0106 方格填数枚举

LQ0090 山枚举

LQ0031 生日蜡烛枚举

LQ0009 平方十位数枚举