问题表示
【问题描述】
小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。在冒泡排序中,每次只能交换相邻的两个元素。小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符,则在所有可能的排序方案中,冒泡排序的总交换次数是最少的。例如,对于字符串lan 排序,只需要1 次交换。对于字符串qiao 排序,总共需要4 次交换。
小蓝的幸运数字是V,他想找到一个只包含小写英文字母的字符串,对这个串中的字符进行冒泡排序,正好需要V 次交换。请帮助小蓝找一个这样的字符串。如果可能找到多个,请告诉小蓝最短的那个。如果最短的仍然有多个,请告诉小蓝字典序最小的那个。请注意字符串中可以包含相同的字符。
【输入格式】
输入一行包含一个整数V,为小蓝的幸运数字。以下N行,包含两个整数A,B。
【输出格式】
输出一个字符串,为所求的答案。
【样例输入】
4
【样例输出】
bbaa
初步想法
打表
第一次看到这个题的时候并没有什么想法,所以打算通过打表来尝试寻找规律。于是首先遍历了N=1-10的情况:
交换次数 | 字符串 | 变化方式 |
---|---|---|
1 | ba | 固定 |
2 | baa | ba+a |
3 | cba | 固定 |
4 | bbaa | b+baa |
5 | cbaa | cba+a |
6 | dcba | 固定 |
7 | cbaaa | cbaa+a |
8 | cbbaa | cbaa插入b |
9 | dcbaa | dcba+a |
10 | edcba | 固定 |
打表后看到的规律
- 每个字符串的逆序数目便等于该字符串变为有序所需要的交换次数。
- ba,cba,dcba这种按照字母表倒序来的是固定的,对应的是(1+2+…+n-1,n-1为字符串长度)的最短冒泡排序字符串。比如:cba是1+2=3位的最短字符串。
- 其他的最短字符串是以后的字符串在某个特定位置插入某个字符的结果。比如:交换次数为4的字符串bbaa是交换次数为2的字符串baa在头部插入b得到的。
规律2,3证明
规律2和规律3直接看起来没那么有说服力,我们通过数学上进行证明,来证明我们提出假设的有效性。
规律2的证明
假设一个字符串 s s s,字符串的长度为 1 + 2 + . . . + n 1+2+...+n 1+2+...+n,如果想要字符串的逆序数最大,每个位置的字符需要满足的条件为 s i − 1 ≥ s i ≥ s i + 1 , i > = 2 s_{i-1} \geq s_i \geq s_{i+1},i>=2 si−1≥si≥si+1,i>=2,其中 s i s_i si表示字符串 s s s第 i i i个位置的字符,即字符串右边的字符总是小于左边的字符。
反证法:假设当字符串长度为 1 + 2 + . . . + n = N 1+2+...+n=N 1+2+...+n=N时,保持原有字符不变,存在一个字符排列 s k s^{k} sk,使得 s k s^{k} sk的逆序数大于 s s s。因为 s k s^{k} sk和 s s s的字符组成都相同,那么 s k s^{k} sk是由 s s s至少交换一对字符得到的。假设交换的字符在 s s s中的位置分别是 i i i和 j j j,其中 i < j i<j i<