题解 | #序列和#

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,即回到优化前的算法

全部评论

相关推荐

06-13 10:15
门头沟学院 Java
想去夏威夷的大西瓜在午休:我也是27届,但是我现在研一下了啥项目都没有呀咋办,哎,简历不知道咋写
点赞 评论 收藏
分享
龙珠传说:nb,公务员解约不需要支付违约金吧
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务