这是牛客上的一道题,题目的名字叫序列和,题干信息如上所示,刚开始我看到这个题的时候有点懵,没有在15分钟内做出来,刚开始我以为可能用到动态规划什么的,因为不可能每种结果都去试一下,但是dp方法我没想出来,看了一下别人的做法,大多都是从数学公式推导角度做的。但是我们不能人云亦云,我们要独立思考对不对。实在想不出来才参考别人的答案,现在我就把自己的方法和代码贡献出来,供大家学习交流,如果我的方法有问题或者改进建议,可以留言或者私信哦。
开始解题:输入非常简单,就是正整数N和最小长度L,不知道你发现了没有,长度L'从给定的最小长度L开始遍历一直到100,如果L'就是满足条件的最小长度,那么如果L'是奇数的话,所求最短连续序列的中间那个数就是N//L',比如题干中的例子:N=18, L'=3,那么所求序列的中间那个数6正好等于N//L' ;那如果满足条件的最小序列长度L'是个偶数呢?举个例子,假如题干变成N=18,L=4,答案就不是5 6 7了,而是3 4 5 6,你发现了吗,L'==L,并且N/L'==4.5,取其下限N//L'==4,而4也正好处于所求连续序列的中间位置,跟L'是奇数的时候一样,那这样就一目了然了,我们只需要求出最短的序列长度L'就可以求出最短的连续序列了,那么怎么求L'呢,上面已经说过了L'从L开始遍历,到100为止,L'存在的话就输出最短连续序列,如果不存在的话就输出No,那么L'存在的判断条件是什么呢?很明显,如果L'存在,那么它必须满足:1、如果L'是奇数,那么L'必须能够被N整除,因为N整除L'的那个数就是连续序列中间的那个数;2、如果L'是偶数,那么L'必须不能被N整除,并且,(N//L'*2+1(中间的两个数之和,比如4+5))*(L'//2(序列的一半长度,相当于偶数个数对折,因为连续序列是对称的啊))。以上两个条件就能求出满足条件的最小序列长度L'。至此,大功告成。(能求出最小序列长度L',这道题就算解出来了),下面附代码:
while True:
try:
res = []
N, L = map(int, input().split())
for i in range(L, 102):
if i%2==1 and N%i==0:
break
elif i%2==0 and N%i!=0 and (N//i*2+1)*(i//2)==N:
break
axis = N//i
if i%2==1 and i!=101:
for j in range(-(i//2), i//2+1):
res.append(axis+j)
print(' '.join(map(str, res)))
elif i%2==0 and i!=101:
for j in range(-(i//2-1), i//2+1):
res.append(axis+j)
print(' '.join(map(str, res)))
elif i==101:
print('No')
except:
break
有些小伙伴可能不理解为什么要加上while循环和try异常退出的条件,这个为了牛客oj系统输入多个测试用例加的,小伙伴们本地测试可以去掉这个while循环,只保留解题的主体就可以(就是把上两行,下两行全去掉即可,注意缩进)。好了本人的解题思路解说完了,想看其他解题方法的请移步牛客网(哈哈,还给牛客引流了呢,不知道牛客给不给广告费,哈哈哈)。牛客原题链接:
https://www.nowcoder.com/questionTerminal/46eb436eb6564a62b9f972160e1699c9
本文原创,转载请注明出处,原创不易,请尊重。