题目描述:
下面的图形是著名的杨辉三角形:
如果我们按从上到下、从左到右的顺序把所有数排成一列,可以得到如下
数列:
1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 6, 4, 1, ...
给定一个正整数 N,请你输出数列中第一次出现 N 是在第几个数?
思路:划分成不同的斜线
1.以每条奇数横线的中心点为斜线的最初值 例如 1,2,6,20 这些值都是c 2n(下标) n 例如2是c2 1
6是c42 20是c63 。我们将其定义为0号斜线(1)、1号斜线(2)、2号斜线(6).......
2.不难发现 每条横线的值规律为c(2n+i)n 例如3是c31 4是c41 10是c52
3.每个值最早出现的地方是优先序列等级高的斜线 例如 6,20,10这些,所以我们需要采用由后往前的方式进行搜索(即从序列等级高的地方搜到到序列等级低的地方)同时,如果此时的值大于需要搜索的值,序列等级(n)-1
C 32 16<1000000000<C 33 16 可得最高是16
idea:
1.进行阶乘的时候可以用res*=a/b 这样如果res>target就能即时退出,优化时间
for i in range(b):
res*=a/b
if res>target:
return res
a-=1
b-=1
return res
2.二分搜索:
low=2*n
high=target
while low<=high:
mid=(low+high)//2
rns=Compute(mid,n)
if rns<target:
low=mid+1
elif rns>target:
high=mid-1
else:
print((mid)*(mid+1)//2+n+1)
return True
low从2n开始 也就是每个序列n初始值的下标
最大是target 比如说搜索10 最大肯定比c10 2 =45要小
3.计算序列方法
mid*(mid+1)//2+n+1
例如target==4 n等于1 mid==4
推一推就可以得到了
import math
from collections import deque
from collections import Counter
import sys
def Compute(a,b):
#a为下限、b为上限
global target
if a<b:
temp=a
a=b
b=temp
res=1
for i in range(b):
res*=a/b
if res>target:
return res
a-=1
b-=1
return res
def Binary_Search(n):
global target
low=2*n
high=target
if low >= high and Compute(low,n)>target:
'''如果最小值都比目标值要大'''
return False
while low<=high:
mid=(low+high)//2
rns=Compute(mid,n)
if rns<target:
low=mid+1
elif rns>target:
high=mid-1
else:
print((mid)*(mid+1)//2+n+1)
return True
return False
target=int(input())
if target==1:
print(1)
sys.exit()
for i in range(16,0,-1):
if Binary_Search(i):
break