混乱的数组 蓝桥杯2024省赛 题解

混乱的数组

题意

在这里插入图片描述
思路如下:

    ① 优先考虑特殊情况,数组是一个严格递减的数组(每个数字之间相差1,最后一位必须为1),例子如下:
            长度为 7 ,对应的数组为 [7,6,5,4,3,2,1],根据组合数学 C(7 , 2) = 21,共有21对逆序对
            长度为 8 ,对应的数组为 [8,7,6,5,4,3,2,1],根据组合数学 C(8 , 2) = 28,共有28对逆序对
        假设逆序对个数为 x 时,当 x ∈ (21,28] ,其数组长度为 8;当 x = 21 时,数组长度为 7
         ② 那么如果 C(L , 2) 不等于 x 呢,假如 x = 25,通过第①步可以求得 L = 7,数组为  [7,6,5,4,3,2,1] ,共 21 对逆序对,那么差4对怎么补齐?其实只要在数组开头添加一个 5 即可,数组变为 [5,7,6,5,4,3,2,1],多了第一个5和黄色的数字组成的逆序对,刚好4对

        当然这个只是其中一个答案,不符合字典序最小的要求。因此需要化简:

              一、   [5,7,6,5,4,3,2,1] 把5改成4 得到 [5,7,6,4,4,3,2,1] ,可以发现逆序对的个数是没有变化的,那是因为原来加粗了的逆序对,改变成了修改后加粗的逆序对,也仅有这一对发生了转移,因此逆序对个数没变,但是字典序变小了。

              

              二、 [5,7,6,4,4,3,2,1]  贪心,把黄色部分都减1 得到 [5,6,5,4,4,3,2,1],很明显逆序对个数依然没有改变,但是字典序变小了。

               

              三、[5,6,5,4,4,3,2,1] 黄色部分改成 [5,6,5,4,3,2,1,1] ,相当于把 4 变成 1 ,可以发现逆序对个数依然没有改变,但是字典序变小了。

                

              四、[5,6,5,4,3,2,1,1] 这情况又和第一步很相似了,把5改成4 得到 [5,6,4,4,3,2,1,1],一直重复步骤一至步骤三,可以得到最终结果:

                                                        [5,4,3,3,2,2,1,1]

                      这个结果就是最"简化"了的,也就是字典序最小

    

    ③ 找规律 x ∈ (21,28] ,结果如下:

混乱的数组 蓝桥杯2024省赛 题解_第1张图片
根据标黄和标红的部分可以发现有很明显的规律,就像两个三角形,或者阶梯更恰当。

黄色阶梯没有标黄的部分,规律都是严格递减的

红色阶梯没有标红的部分,除了开头那个数字,规律都是严格递减的,而开头的数字跟加粗的数字是相等的

最终的规律总结如下所示:

1、应为n+1长度
2、最终序列可看成是三递减序列的组合:数字a、a-1递减序列和b递减序列。且a+b==n+1。
3、三个序列的组合规律是:先把a-1序列和b递减序列组合,然后降序排序,然后把a插入到头部。

python代码

import sys
from collections import Counter
from heapq import *
input = lambda: sys.stdin.readline().strip()
x = int(input())
if x == 0 :
    print(1)
else :
    def get(x) :
        return x * (x - 1) // 2
    i = 2
    while get(i) < x :
        i += 1
    ans = []
    n = i
    n -= 1
    a = x - get(n) + 1
    b = n + 1 - a
    for i in range(1 , a) :
        ans.append(i)
    for i in range(1 , b + 1) :
        ans.append(i)
    ans.sort(reverse=True)
    ans.insert(0 , a)
    print(n + 1)
    for x in ans :
        print(x , end = ' ')

你可能感兴趣的:(蓝桥杯,算法,数据结构,python,java,c++,c语言)