目录
模板
先定义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
例题
求最大值例题分巧克力
题目链接
小明—共有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)
求最小值例题求阶乘
题目链接
满足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')