第八届蓝桥杯赛题 分巧克力(用二分法实现)

发布时间 2023-12-12 17:39:03作者: 南笙西瓜

今日一道编程题  第八届蓝桥杯赛题中的分巧克力问题(用二分法实现)

问题描述如下:

儿童节那天有K位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。小明一共有N块巧克力,其中第i块是Hi x Wi的方格组成的长方形。为了公平起见,小明需要从这 N 块巧克力中切出K块巧克力分给小朋友们。切出的巧克力需要满足:

  1. 形状是正方形,边长是整数  

  2. 大小相同 

  例如一块6x5的巧克力可以切出6块2x2的巧克力或者2块3x3的巧克力。当然小朋友们都希望得到的巧克力尽可能大,你能帮小明计算出最大的边长是多少么?

输入格式:

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

输出格式:

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

以下是我的解题思路:

用二分法实现:

#include<bits/stdc++.h>
using namespace std;
int n, k;
int h[100010], w[100010];
bool check(int d) {
    int num = 0;
    for (int i = 0; i < n; i++)
        num += (h[i] / d) * (w[i] / d);
    if (num >= k) return true;    //够分
    else       return false;   //不够分
}
int main() {
    cin >> n >> k;
    for (int i = 0; i < n; i++)   cin >> h[i] >> w[i];
 
    int L = 1, R = 100010;
 
    while (L < R) {
        int mid = (L + R + 1) >> 1;   //除2,向右取整
        if (check(mid))
            L = mid;  //新的搜索区间是右半部分,所以R不变,调整L=mid;
        else
            R = mid - 1; //新的搜索区间是左半部分,所以L不变,调整R=mid–1。
    }
    cout << L;
 
    return 0;
}