• LQ0153 字串排序【排序】


    题目来源:蓝桥杯2020初赛 C++ A组J题

    题目描述
    小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。
    在冒泡排序中,每次只能交换相邻的两个元素。
    小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符,则在所有可能的排序方案中,冒泡排序的总交换次数是最少的。
    例如,对于字符串lan 排序,只需要1 次交换。对于字符串qiao 排序,总共需要4 次交换。
    小蓝的幸运数字是V,他想找到一个只包含小写英文字母的字符串,对这个串中的字符进行冒泡排序,正好需要V 次交换。请帮助小蓝找一个这样的字符串。
    如果可能找到多个,请告诉小蓝最短的那个。
    如果最短的仍然有多个,请告诉小蓝字典序最小的那个。
    请注意字符串中可以包含相同的字符。

    输入格式
    输入第一行为T,表示存在T组测试数据。(T≤25)
    对于每组测试数据,输入一行包含一个整数V,为小蓝的幸运数字。
    对于所有评测用例,1 ≤ V ≤ 10000。

    输出格式
    每组测试数据,输出一个字符串,为所求的答案。

    输入样例
    2
    4
    100

    输出样例
    bbaa
    jihgfeeddccbbaa

    问题分析
    这个题跟《LQ0149 排序【枚举】》类似,只是允许字母可以重复出现。
    蓝桥杯官网的测试数据是单输入的。
    解题程序是CV来的,其算法逻辑还没有搞明白。这个解题代码似乎有点问题。
    募集解题程序,有正确代码请跟帖。

    AC的C++语言程序(蓝桥杯官网)如下:

    /* LQ0153 字串排序 */
    
    #include 
    #include 
    
    using namespace std;
    
    const int N = 26;
    int v, len, now, cnt[N + 1], sum[N + 1];
    
    int getlen(int len)
    {
        int q = len / N;
        int r = len % N;
        return ((len - q - 1) * (q + 1) * r + (N - r) * q * (len - q)) / 2;
    }
    
    bool judge(int k , int d)
    {
        memset(cnt , 0 , sizeof cnt);
    
        int add1 = 0, add2 = 0;
        for(int j = N; j >= k + 1; j--)
            add1 += sum[j];
        sum[k]++;
        for (int L = 1; L <= d; L++){
            int ma = -1, pos = 0, num = 0;
            for (int j = N ; j >= 1 ; j--){
                if (L - 1 - cnt[j] + num > ma) {
                    ma = L - 1 - cnt[j] + num;
                    pos = j;
                }
                num += sum[j];
            }
            add2 += ma, cnt[pos]++;
        }
        if (now + add1 + add2 >= v) {
            now += add1;
            return true;
        } else {
            sum[k]-- ;
            return false;
        }
    }
    
    int main()
    {
        cin >> v;
    
        len = 1;
        while (getlen(len) < v)
            len++;
    
        string ans;
        for (int i = 1; i <= len; i ++)
            for(int j = 1; j <= N; j++)
                if (judge(j , len - i)) {
                    ans += char(j + 'a' - 1);
                    break ;
                }
    
        cout << ans << endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
  • 相关阅读:
    microk8s拉取pause镜像卡住
    749个看图识字含MP3音频ACCESS\EXCEL数据库
    C和指针 第10章 结构和联合 10.10 问题
    Sulfo-CY7 NHS ester荧光染料的合成与化学性质1603861-95-5
    深度学习二分类评估详细解析与代码实战
    Java实现数字的千分位的处理
    Youtube新手运营——你需要的技巧与工具
    SpringCloud微服务---Nacos配置中心
    形态学 - 凸壳
    ADC采集到的数值和电压值、频率有什么联系?
  • 原文地址:https://blog.csdn.net/tigerisland45/article/details/127723549