蓝桥杯精选赛题算法系列——分巧克力——二分法

今天是第二个算法——二分法。

二分法

**引入:**来做个游戏:给你一个1~100之内的数字,你必须要在 7 次内猜出这个数字,怎么猜?
这个时候就要派上我们的二分法:
演示一下:
例如这个数是54,我问你7次:
大于等于50吗?是。(1~100二分,中位数是50)
大于等于75吗?否。(50~100二分,中位数是75)
大于等于63吗?否。(50~75二分,…)
大于等于56吗?否。
大于等于53吗?是。
大于等于54吗?是。
等于55吗?否。
那么这个数等于54。懂个大概了吗?

下面我来给出python的二分法模板

def check(a,n,x):
    left = 0
    right = n 
    while left < right:
        mid = left +(right-left)//2
        if a[mid] >= x:
            right = mid
        else:
            left = mid +1
        print(a[mid])
    return left
n = 100 
test = 54
a = [0 for _ in range(1000)]
for i in range(n):
    a[i] = i+1
print(a)
ans = check(a,n,test)
print('test = %d'%a[ans])

check() 操作 3个变量:区间左端点 left、右端点 right、二分的中位数 mid。每次把区间缩小一半,把 left 或 right 移动到 mid;直到 left = right 为止,即找到了答案所处的位置。
当 a[mid] >= x 时,说明 x 在 mid 的左边,新的搜索区间是左半部分,left 不变,更新 right = mid。
当 a[mid] < x 时,说明 x在 mid 的右边,新的搜索区间是右半部分,right 不变,更新 left = mid + 1。
代码执行完毕后,left = right,两者相等,即答案所处的位置。代码很高效,每次把搜索的范围缩小一半,总次数是 log(n)​。
下面直接上例题:

题目描述

儿童节那天有 K 位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。
小明一共有 N 块巧克力,其中第 i 块是 Hi ×Wi 的方格组成的长方形。为了公平起见,小明需要从这 N 块巧克力中切出 K 块巧克力分给小朋友们。切出的巧克力需要满足:
1.形状是正方形,边长是整数;
2.大小相同;
例如一块6×5​ 的巧克力可以切出 6 块2×2​ 的巧克力或者 2 块3×3 的巧克力。
当然小朋友们都希望得到的巧克力尽可能大,你能帮小明计算出最大的边长是多少么?

输入描述

第一行包含两个整数 N,K (1≤N,K≤10 5 )。
以下 N 行每行包含两个整数 Hi,Wi(1 <= Hi, Wi <= 105)。
输入保证每位小朋友至少能获得一块 1×1 的巧克力。

输出描述

输出切出的正方形巧克力最大可能的边长。

样例输入

2 10
6 5
5 6

样例输出

2
def check(d):
    global w,h
    res = 0
    for i in range(len(w)):
        res += (w[i]//d) * (h[i]//d)
    if res >= k:  return True
    return False
n,k = map(int,input().split())
w = []
h = []
for i in range(n):
    a,b = map(int,input().split())
    w.append(a)
    h.append(b)
L ,R = 1, 10000
while L < R:
    mid = (L+R)//2
    if check(mid):  L = mid +1
    else :          R = mid
print(L-1)

这个题就是运用了二分法。
下课题见。

猜你喜欢

转载自blog.csdn.net/m0_51951121/article/details/122675107