题解 | #序列和#
https://www.nowcoder.com/practice/46eb436eb6564a62b9f972160e1699c9
target, n = map(int, input().split()) k = n i = (target - k*(k-1)//2)//k if i<0: i=0 j = n + i - 1 res = n ans = [] while True: if k>100: print('No') break total = (i+j)*k/2 if total == target: for x in range(k): ans.append(i) i+=1 print(' '.join(map(str, ans))) break elif total < target: i+=1 j+=1 elif total>target: k += 1 i = (target - k*(k-1)//2)//k if i<0: i=0 j = k + i - 1
第一次使用ACM模式,所以输入输出写的不是很优雅,还望见谅
算法的思路就是,从目标的长度和L作为初始的滑动窗口长度,开始滑动,从[0,0+L-1]开始,使用等差数列求和计算totai与目标和N比较,小则移动,大则退出,尝试L+1长度的滑动窗口,因为提的目的是找>=L的最小长度的,所以从L出发,若是有那就可以节省很大的计算量,但是当遇到N很大的情况,该算***超时
于是,优化:i的初始值从0优化至(N-k(k-1)//2)//k,其中k则是滑动窗口的长度,初始值为L,每次循环+1,并约束i>0,若是负数,则直接赋给0,即回到优化前的算法