1. 程式人生 > 其它 >寒假每日一題(七)—— 分巧克力 整數二分

寒假每日一題(七)—— 分巧克力 整數二分

技術標籤:2021寒假每日一題c++演算法二分法

文章目錄

分巧克力

兒童節那天有 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≤105,
1≤Hi,Wi≤105
輸入樣例:

2 10
6 5
5 6

輸出樣例:

2

分析

我們可以把問題分解成對於每個巧克力可以分成多少塊x*x面積的巧克力:(w[i]/x)*(h[i]/x),直接用整數二分來選取x的值就可以了!!

程式碼

#include<iostream>
#include<algorithm>
#include<string>
#include<vector> using namespace std; const int N = 100010; int w[N], h[N]; int n, m; bool check(int mid) { int sum = 0; int numw = 0; int numh = 0; for (int i = 0; i < n; i++) { numw = w[i] / mid; numh = h[i] / mid; sum += (numh*numw); if (sum >= m)return true; } return false; } int
main() { cin >> n >> m; for (int i = 0; i < n; i++) { cin >> w[i] >> h[i]; } int l = 0, r = 100010; while (r > l) { int mid = (r + l + 1) >> 1; if (check(mid)) { l = mid; } else { r = mid - 1; } } cout << l << endl; return 0; }

執行結果

在這裡插入圖片描述