备战蓝桥杯历年试题:杨辉三角形 省赛B组 Python详解

导语:距离蓝桥杯70天 该加油就努力 借用路飞哥一句话 不要碌碌无为还安慰自己平凡可贵

直接上图: 题目可以到官网的历年试题中找到 

 

程序设计需具备以下几点知识:

1:了解杨辉三角数对称的性质 以及C(n,m)的计算方法(n下标m上标)

2:会编写组合数函数C(n,m)

3:会二分查找

 杨辉三角分析:(手写字不太好看见谅)

 !继上面所说的 我们只需要从内行到外行进行遍历

下面确定遍历范围:由于数据范围1<=N<=1000000000

>>> C(32,16)
601080390
>>> C(34,17)
2333606220   所以根据上面所说的 我们只需要掌握到第16斜行即可 因为17斜行最小的元素都大于1000000000 所以不会出现N   18,19..行依次类推

所以现在的任务就是 从第16斜行遍历到第1斜行:查找N存在的位置(开始二分查找)

                                                二分查找就需要范围 

如何确定:第i斜行 若首个元素(最小元素)C(2i,i)大于N

说明不会出现第i斜行 因为斜行向下递增 

若首个元素(最小元素)C(2i,i)小于N 在该斜行查找

首先 C(n,1)=n 即一定有一个符合输入的N出现在第n行(正行)

其次:斜行上的每一个数字都可以用C(2i,range)来表示 

n就是我们要规划的范围 斜行元素最小时 range=i 

划重点!斜行元素最大不能超过C(2i,N) 原因在于 第N正行已经存在N  它的右侧元素都大于N

所以正行再往下数就没意义了!

所以我们得到二分的区间范围range∈(i,N)(N<i则不运行)

如果在该斜行没找到就继续向上一个斜行找.....

最糟糕的情况就是找到了第2斜行 N最终还是会出现滴


N=int(input())

def C(a,b):#阶乘函数
    res=1
    i,j=a,1
    while j<=b:
        res=res*i/j
        i-=1
        j+=1
    return int(res)
def find(j,N):
    l,r=2*j,N
    while l<=r:#二分模板
        mid=(l+r)//2
        if C(mid,j)==N:
            print(int(mid*(mid+1)/2)+j+1)
            return True
        elif C(mid,j)>N:
            r=mid-1
        else:
            l=mid+1
    return False  
for i in range(16,-1,-1):
    if find(i,N):
        break

指出:代码中int(mid*(mid+1)/2)+j+1不可以改成 int(mid*(mid+1)/2+j+1) 涉及到精度问题 详见(否则将只有80分)关于Python精度问题icon-default.png?t=M0H8https://ask.csdn.net/questions/7637793?weChatOA=weChatOA1

如果还有哪里没有讲清楚的欢迎评论留言 这道题还是一道思维题 

                        ​​​​​​​        ​​​​​​​        ​​​​​​​       新年快乐 不忘为算法奋斗!加油

评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Py小郑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值