题目来源:蓝桥杯2020初赛 Java B组E题
题目描述
小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。
在冒泡排序中,每次只能交换相邻的两个元素。
小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符,则在所有可能的排序方案中,冒泡排序的总交换次数是最少的。
例如,对于字符串lan 排序,只需要1 次交换。对于字符串qiao 排序,总共需要4 次交换。
小蓝找到了很多字符串试图排序,他恰巧碰到一个字符串,需要100 次交换,可是他忘了吧这个字符串记下来,现在找不到了。
请帮助小蓝找一个只包含小写英文字母且没有字母重复出现的字符串,对该串的字符排序,正好需要100 次交换。如果可能找到多个,请告诉小蓝最短的那个。如果最短的仍然有多个,请告诉小蓝字典序最小的那个。
这是一道结果填空的题,你只需要算出结果后提交即可。
本题的结果为一个只包含小写英文字母的字符串,在提交答案时只填写这个字符串,填写多余的内容将无法得分。
问题分析
根据冒泡排序的交换字数进行计算,先算出需要的字符串长度。先考虑最多交换次数,再做调整。
AC的C语言程序如下:
/* LQ0149 排序 */
#include
#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;
}