兒童節那天有 K 位小朋友到小明家做客。
小明拿出了珍藏的巧克力招待小朋友們。
小明一共有 N 塊巧克力,其中第 i 塊是 Hi×Wi 的方格組成的長方形。
為了公平起見,小明需要從這 N 塊巧克力中切出 K 塊巧克力分給小朋友們。
切出的巧克力需要滿足:
- 形狀是正方形,邊長是整數
- 大小相同
例如一塊 6×5 的巧克力可以切出 6 塊 2×2 的巧克力或者 2 塊 3×3 的巧克力。
當然小朋友們都希望得到的巧克力儘可能大,你能幫小明計算出最大的邊長是多少麼?
輸入格式
第一行包含兩個整數 N 和 K。
以下 N 行每行包含兩個整數 Hi 和 Wi。
輸入保證每位小朋友至少能獲得一塊 1×1 的巧克力。
輸出格式
輸出切出的正方形巧克力最大可能的邊長。
資料範圍
1≤N,K≤1e5,
1≤Hi,Wi≤1e5
輸入樣例:
2 10
6 5
5 6
輸出樣例:
2
題解:
(ps: 一道簡單的二分, 程式碼中有很詳細的註釋, 不多解釋了, 看不懂的話可以再問)~
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int a[N], b[N]; // 儲存巧克力的長寬
int n, m, mx = 0;
bool check(int mid)
{
int sum = 0; // 以 mid 為邊長的巧克力總塊數
for (int i = 0; i < n; i ++)
{
int x = a[i] / mid, y = b[i] / mid;
sum += x * y;
}
return sum >= m;
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i ++)
{
cin >> a[i] >> b[i];
mx = max(a[i], mx); mx = max(b[i], mx); // mx 是二分的右邊界, 即輸入的邊長最的最大值
}
int l = 1, r = mx;
while (l < r)
{
int mid = l + r + 1 >> 1;
if (check(mid)) l = mid; // if sum >= m, 說明巧克力的邊長小了, 或者是 剛好
else r = mid - 1; // sum < m 邊長 大了
}
cout << l << endl; // 題目保證了有解, 不需要加判斷了
return 0;
}
覺得不錯的話, 點個贊吧~