zzt002279


私信TA

用户名:dotcpp0672134

访问量:974

签 名:

等  级
排  名 12352
经  验 976
参赛次数 0
文章发表 2
年  龄 0
在职情况 学生
学  校
专  业

  自我简介:

解题思路:


借鉴了大佬的思想,在此表示崇敬和感谢。

https://blog.dotcpp.com/a/95964

 

站在大佬的肩膀上,进一步发现了更容易编程的规律:每个x对应的数组由三个序列构成。



整体思想和注意事项:

1、特殊情况


图片1.png

  


即:以n开头的递减序列,其对应的x为: n*(n-1)//2

 

只要遇到 x,反推得到n,恰好满足:n*(n-1)//2==x,那么序列就是:n n-1 n-2 n-3....1

 

2、其他情况

若遇到x,不能恰好满足特殊情况,就先找到一个满足 n*(n-1)//2<x 的最大的n。

下面是最笨的穷举法:

def f2(n): # return n*(n-1)//2

    return n*(n-1)//2

 

def f(x):# n*(n-1)<=2*x,返回最大的n

    for n in range(2,100000):

        y=f2(n)

        if y==x:

            return n

        elif y>x:

            return n-1

 

比如:

x=22,得到n=7,那么只需要在序列 7654321 前面加上 a=x-n*(n-1)//2+1=2 的数字即可得到一个解:27654321

依次类推。

但这个解不是字典序最小的。还需要想办法调整。

观察下面表中规律。【此数据来自大佬页面】

 图片2.png

  

当在长度为n的递减序列前面添加a后,对应的最终序列有下面规律:

1、应为n+1长度

2、最终序列可看成是三递减序列的组合:数字a、a-1递减序列和b递减序列。且a+b==n+1。

3、三个序列的组合规律是:先把a-1序列和b递减序列组合,然后降序排序,然后把a插入到头部。

 

计算得到n

y=x-n*(n-1)//2

a=x-y+1

b=n+1-a

L=[]

for i in range(1,a):

    L.append(i)

for j in range(1,b+1):

    L.append(j)

L.sort(reverse=True)

L.insert(0,a)  

 


参考代码:

import sys,math
 
 
def f2(n): # return n*(n-1)//2
    return n*(n-1)//2
 
def f(x):# n*(n-1)x:
            return n-1
 
    
 
x=int(input())
 
n=f(x)
 
y=f2(n)
   
#print("1:",n)
L=[]
 
if y==x:#满足特殊情况的序列
    a=0
    b=n
    for i in range(b,0,-1):
        L.append(i)
else:#一般序列
    #最终的序列由两个序列组合而成,
    #a开始的递减序列和b开始的递减序列,a+b==n+1,a是要添加的数字
    #如果a>=b,直接合并,降序即可
    #如果a<b,则是a-1递减序列和b递减序列合并、降序,再在结果前面添加a
 
    #可统一为:a-1递减序列和b递减序列合并、降序,再在结果前面添加a
    a=x-y+1 #a是最高位要添加的数
    b=n+1-a #b是另一个序列的开始值
    #print(n,a,b)
 
    
    for i in range(1,a):
            L.append(i)
    for j in range(1,b+1):
        L.append(j)
    L.sort(reverse=True)
    L.insert(0,a)       
 
 
 
print(len(L))
for x in L:
    print(x,end=" ")


 

0.0分

3 人评分

  评论区

  • «
  • »