2017年蓝桥杯省赛分巧克力
描述
儿童节那天有K位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。
小明一共有N块巧克力,其中第i块是Hi x Wi的方格组成的长方形。
为了公平起见,小明需要从这N 块巧克力中切出K块巧克力分给小朋友们。切出的巧克力需要满足:
-
形状是正方形,边长是整数
-
大小相同
例如一块6x5的巧克力可以切出6块2x2的巧克力或者2块3x3的巧克力。
当然小朋友们都希望得到的巧克力尽可能大,你能帮小Hi计算出最大的边长是多少么?
输入
第一行包含两个整数N和K。(1 <= N, K <= 100000)
以下N行每行包含两个整数Hi和Wi。(1 <= Hi, Wi <= 100000)
输入保证每位小朋友至少能获得一块1x1的巧克力。
输出
输出切出的正方形巧克力最大可能的边长。
输入样例 1
2 10
6 5
5 6
输出样例 1
2
基本思路:
- 先求出最大边长,因为最大的巧克力不可能超过最大边长
- 求解每块巧克力能分成多少块小的巧克力
- 先从小的巧克力开始分,然后逐渐增大巧克力的大小(暴力解法,会超时)。在更新巧克力的面积时可以使用二分查找
N_K_list = input() # 读取输入,为一个字符串
n, k = map(int, N_K_list.split()) # 分割字符并读取
foods = []
max_side = 0
for _ in range(n):
food = input().split()
h, w = map(int, food)
max_side = max(max_side, h, w) # 存储最大边长
foods.append((h, w))
def get_num(h, w, num):
num1 = h // num
num2 = w // num
return num1 * num2
head = 1
tail = max_side
result = 0
while head <= tail: # 循环条件
mid = (head + tail) // 2
total_pieces = sum(get_num(h, w, mid) for h, w in foods) # 计算所有巧克力能分多少块小的巧克力
if total_pieces >= k:
result = mid
head = mid + 1
else:
tail = mid - 1
print(result)