python之二分法求最值

目录

模板

例题


模板

先定义check函数用于是否判断满足条件

初始化L指针定义在最左边,R指针定义在最右边

循环条件:L<R

循环结束后输出L即为结果

求最大值循环体

while L < R:
    mid = (L + R + 1) // 2  
    if 满足条件:  
        L = mid
    else: 
        R = mid - 1

求最小值循环体

while L < R:
    mid = (L + R) // 2  
    if 满足条件:  
        R = mid
    else: 
        L = mid + 1

例题

求最大值例题分巧克力

题目链接

https://www.lanqiao.cn/problems/99/learning/?page=1&first_category_id=1&sort=students_count&category_id=3&name=%E5%88%86%E5%B7%A7%E5%85%8B%E5%8A%9B

小明—共有N块巧克力,其中第i块是Hi× Wi的方格组成的长方形。为了公平起见,小明需要从这N块巧克力中切出K块巧克力分给小朋友们。切出的巧克力需要满足:

1.形状是正方形,边长是整数  2.大小相同;

例如—块6x5的巧克力可以切出6块2x2的巧克力或者2块3x3的巧克力。小朋友们都希望得到的巧克力尽可能大,请计算出最大的边长

N, K = map(int, input().split())
h = []
w = []
for i in range(N):
    a, b = map(int, input().split())
    h.append(a)
    w.append(b)


def check(x):  # 边长为x时一共可以切出多少个巧克力
    sum = 0
    for i in range(N):  # 对每块巧克力进行循环
        sum = sum + (h[i] // x) * (w[i] // x)  # 长边除以边长乘短边除以边长就是一块能分成的数量
    return sum


L, R = 1, 1000000

while L < R:
    mid = (L + R + 1) // 2  # 找最大值时加1防止死循环
    if check(mid) >= K:  # 满足条件,由于找最大值,继续在mid的右边搜索,不能舍弃mid,所以令l=mid
        L = mid
    else:  # 说明mid太大,mid及其右边的数都可以舍弃,所以令r=mid-1
        R = mid - 1

print(L)

求最小值例题求阶乘

题目链接

https://www.lanqiao.cn/problems/2145/learning/?page=30&first_category_id=1&sort=students_count&category_id=3&second_category_id=3

满足n!的末尾恰好有K个0的最小的n是多少?如果这样的N不存在输出-1。
 

0的个数由因子2和5相乘得到,而在阶乘中,2的数量肯定比5多,也就是说0的个数就等于因子5的个数,然后我们要知道求阶乘因子个数的一个性质,快速计算n!的因子q的个数代码如下

def count(n,q):
    ans = 0
    while n // q:
        ans = ans + n // q
        n = n // q
    return ans

例如求25!中因子5的个数

25=1*2*3*…*25

25//5=5,相当于在1到25中5的倍数有5个(5,10,15,20,25),

5//5=1,相当于在1到5中5的倍数有1个(5)

所以最后25!中因子5的个数有5+1=6个

def check(n):  # 计算n!有多少个因子5
    count = 0
    while n // 5:
        count += n // 5
        n = n // 5
    return count


K = int(input())
L = 1
R = 10 ** 18
while L < R:
    mid = (L + R) // 2
    if check(mid) >= K:  # 满足条件,由于找最小值,所以继续在mid左边搜索,mid不能舍弃,所以令r=mid
        R = mid
    else:  # 不满足条件,说明mid太小,mid及其左边的数都可以舍弃,所以令l = mid + 1
        L = mid + 1

if check(L) == K:
    print(L)
else:
    print('-1')

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Genius256

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

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

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

打赏作者

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

抵扣说明:

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

余额充值