借鉴了大佬的思想,在此表示崇敬和感谢。
https://blog.dotcpp.com/a/95964
站在大佬的肩膀上,进一步发现了更容易编程的规律:每个x对应的数组由三个序列构成。
即:以n开头的递减序列,其对应的x为: n*(n-1)//2
只要遇到 x,反推得到n,恰好满足:n*(n-1)//2==x,那么序列就是:n n-1 n-2 n-3....1
若遇到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
依次类推。
但这个解不是字典序最小的。还需要想办法调整。
观察下面表中规律。【此数据来自大佬页面】
当在长度为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 人评分
【明明的随机数】 (C语言代码)浏览:845 |
2004年秋浙江省计算机等级考试二级C 编程题(1) (C语言代码)浏览:676 |
简单的a+b (C语言代码)浏览:574 |
C语言程序设计教程(第三版)课后习题8.1 (C语言代码)浏览:606 |
C语言程序设计教程(第三版)课后习题8.2 (C语言代码)浏览:1108 |
拆分位数 (C语言代码)浏览:558 |
C语言程序设计教程(第三版)课后习题7.3 (C语言代码)浏览:461 |
C语言程序设计教程(第三版)课后习题1.5 (C语言代码)浏览:518 |
字符串的修改 (C语言代码)浏览:1206 |
C语言训练-求PI* (C语言代码)浏览:520 |