分巧克力

题目描述

        儿童节那天有 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​≤10^5)。

输入保证每位小朋友至少能获得一块 1x1 的巧克力。

输出描述

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

输入输出样例

示例

输入

2 10
6 5
5 6

输出

2

运行限制

  • 最大运行时间:2s
  • 最大运行内存: 256M

代码实现

#include
using namespace std;

int N, K; // N是巧克力的块数,K是小朋友的数量
int H[100005], W[100005]; // H和W数组分别存储每块巧克力的高度和宽度
int ans = 0; // 用于存储最终结果,不过在这个实现中未直接使用

// 检查是否可以切出至少K个边长为x的正方形巧克力块
bool check(int x) {
    int count = 0; // 用于统计可以切出的正方形数量
    for (int i = 0; i < N; ++i) {
        int t1 = H[i] / x; // 计算当前巧克力块可以切出的行数
        int t2 = W[i] / x; // 计算当前巧克力块可以切出的列数
        count += t1 * t2; // 累加可以切出的正方形数量
    }
    if (count >= 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 = 100000, mid = 0; // 初始化二分查找的边界
    while (l <= r) {
        mid = (l + r) >> 1; // 计算中间值
        if (check(mid)) { // 如果边长为mid合法
            l = mid + 1; // 尝试更大的边长
        } else {
            r = mid - 1; // 尝试更小的边长
        }
    }
    
    // 输出最大可能的正方形边长
    // 最终r会停在满足条件的最大边长上,因为当check(mid)为true时,l会增大
    cout << r;
    return 0;
}

你可能感兴趣的:(算法,蓝桥杯刷题,算法,数据结构,蓝桥杯)