【问题描述】
【解题思路】
刚开始看这道题想着直接暴力,通过公式依次算出每个元素再和正整数N比较,结果超时,只能通过前四个样例。
组合数计算占用了大量的时间,使用动态规划来计算杨辉三角,提交超时一气呵成:(,接着我们只能找一找这些数之间的规律了:
#示例
[1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1]
[1, 11, 55, 165, 330, 462, 462, 330, 165, 55, 11, 1]
[1, 12, 66, 220, 495, 792, 924, 792, 495, 220, 66, 12, 1]
[1, 13, 78, 286, 715, 1287, 1716, 1716, 1287, 715, 286, 78, 13, 1]
[1, 14, 91, 364, 1001, 2002, 3003, 3432, 3003, 2002, 1001, 364, 91, 14, 1]
[1, 15, 105, 455, 1365, 3003, 5005, 6435, 6435, 5005, 3003, 1365, 455, 105, 15, 1]
1.所要查找的正整数N一定存在,最差结果为出现位置在第N行第二列(行从0开始);
2.所要查找的正整数N第一次出现的位置只可能是每一行的前半部分;
3.每一行的数字都增长的特别快,其实需要判断的部分没那么多。
#第1900行的前几个数
1, 1900, 1804050, 1141362300, 541291070775,205257574037880, 64827183800297100,
我们可以发现大约在1900行之后,正整数N只可能出现在第二个或者第三个位置上面,所以在1900行之后,我们只需要通过公式来计算这两个位置的数,依次比较即可。
【具体代码】
n = int(input())
if n == 1:
print(1)
else:
res = n * (n + 1) / 2 + 2
batch = 1
dp= [1,1]
pre = 3
flag = 1
while batch < 1900 and flag:
listN = [1]
pre += 1
for i in range(1,len(dp)):
temp = dp[i-1] + dp[i]
pre += 1
listN.append(temp)
if temp == n:
print(pre)
flag = 0
break
if not flag:
break
listN.append(1)
dp = listN
pre += 1
batch += 1
if batch == 1900:
temp = int(n ** 0.5)
while temp * (temp - 1) // 2 < n:
temp += 1
if temp * (temp - 1) // 2 == n:
print(temp * (temp + 1) // 2 + 3)
else:
print(n * (n + 1) // 2 + 2)
【提交截图】