问题描述
小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。
在冒泡排序中,每次只能交换相邻的两个元素。
小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符,则在所有可能的排序方案中,冒泡排序的总交换次数是最少的。
例如,对于字符串 lan 排序,只需要 次交换。对于字符串 qiao 排序,总共需要 次交换。
小蓝的幸运数字是 ,他想找到一个只包含小写英文字母的字符串,对这个串中的字符进行冒泡排序,正好需要 次交换。请帮助小蓝找一个这样的字符串。如果可能找到多个,请告诉小蓝最短的那个。如果最短的仍然有多个,请告诉小蓝字典序最小的那个。请注意字符串中可以包含相同的字符。
输入格式
输入一行包含一个整数 ,为小蓝的幸运数字。
输出格式
输出一个字符串,为所求的答案。
一、问题分析?
样例输入
100
样例输出
jihgfeeddccbbaa
- 由样例输出可以看出,输出字符串字母一定是字典序倒序排列的
- 那么我们假设字符串为gfedcba,字符串长度为n,此时n=7。g需要交换n-1=6次;f需要n-2次。那么总共需要(n-1)*n/2次。
- 那么(n-1)*n/2>100,解得n>=15。也就是n至少是15才能满足能够字符串交换100次。
- 确定n=15了,然后发现,每多一个aa或者bb等两个相邻且相同的,就会少交换一次。按照规律可发现:
字符串 ->少交换次数
aa ->1
aaa->2+1
aaaa->3+2+1
aaaaa->4+3+2=1
m个a->(m-1)*m/2
-
所以我们只需要用n个字符串交换的最大次数减去少交换的等于要交换的就OK了
-
那么如何确定少交换的字符串是什么呢
-
长度15的字符串,最多交换105次,比预计多5次,就可以知道少交换5次就可以了,所以会有aabbccddee
-
用编程需要去判断的话就是,先找到aaaa少交换了6次,所以从aaaa往前推,测试aaa、aa,直到找到合适的i个aa和j和aaa恰好能够少交换5次。
-
但是找到了两个解,分别是aaabb,以及aabbccddee都能少交换五次。我们可以保存到best数组里;
aaabb格式为:32
aabbccddee格式为:22222 -
但是题目要求字典序最小,所以还要比较字典序
jihgfeeddccbbaa
lmjihgfedcbbbaa
明显22222的字典序最小,所以比较best数组中数字的多少就可以判断了。 -
当数组中数字个数一样,需要比较最大数字的大小,也就是3>2,所以22222是字典序最小的,自己可以写写比较测试一下。
-
解析就到这里,萌新一个,字丑勿怪,见代码。
二、代码
1.引入库
代码如下(示例):
import java.util.Scanner;
import javax.print.attribute.standard.RequestingUserName;
public class Main {
private static int []best;
private static int []good;
private static int bestcount=0;
private static int goodcount=0;
public static void main(String[] args) {
Scanner scanner =new Scanner(System.in);
int v=scanner.nextInt();
int strlen=strLen(v);
//System.out.println(strlen);
int rest=strlen*(strlen-1)/2-v;
//System.out.println(rest);
best=new int [strlen]