從最小的可能解次屠,到最大的可能解之間园匹,通過(guò)二分查找,驗(yàn)證每一個(gè)mid是否為解劫灶。
二分的過(guò)程是這樣的:
定義變量ans裸违,儲(chǔ)存當(dāng)前優(yōu)解。定義閉區(qū)間[left, right]本昏,代表程序當(dāng)前正在此閉區(qū)間內(nèi)尋找答案(尋找潛在的比ans更優(yōu)的解)供汛。
令mid = (left + right)/2
若mid為解,則ans = max(ans, mid), left = mid + 1. 此時(shí)我們更新了最優(yōu)解,同時(shí)在最優(yōu)解的右側(cè)尋找潛在的更優(yōu)解怔昨。
若mid不為解雀久,則right = mid - 1. mid不是解,因此我們?cè)趍id左邊尋找更優(yōu)解趁舀。
重復(fù)上述過(guò)程赖捌,直到left > right時(shí)跳出循環(huán),ans即為最優(yōu)解矮烹。
#include <iostream>
using namespace std;
int h[100001], w[100001], n, k;
bool check(int x) {
int s = 0;
for (int i = 1; i <= n; i++) {
s += (h[i]/x) * (w[i]/x);
}
return s >= k;
}
int main() {
cin >> n >> k;
for (int i = 1; i <= n; i++) {
cin >> h[i] >> w[i];
}
int low = 1, high = 10000, ans = 0;
while (low <= high) {
int mid = low + (high-low)/2;
if (check(mid)) {
low = mid + 1;
ans = max(ans, mid);
} else {
high = mid - 1;
}
}
cout << ans << endl;
return 0;
}