LQ0153 字串排序排序
Posted 海岛Blog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 <iostream>
#include <cstring>
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;
以上是关于LQ0153 字串排序排序的主要内容,如果未能解决你的问题,请参考以下文章