二分答案
做二分的题,发现只要是用二分答案解题的题目,大概率让我们自己设问题答案为x,给我们一个k,这个k与x不是正相关就是负相关。然后check(x)偏大时,就让x变小,也就是r = mid;check(x)偏小时,就让x变大,也就是l = mid。
这题也是这个思路。设答案,也就是月饼高度为x。(实际main函数中没有x,但是l与r这个区间就代表了答案x的范围,我们将要对这个区间进行二分,寻找正确答案)当check的月饼个数小于k,代表高度x选大了,那么就让r = mid;当check的月饼个数大于k,代表高度x选小了,那么就让l = mid。看出本题x与k成负相关。
若check的月饼个数等于k,令l = mid,输出l的值就行。(因为要找的是极限值,就是要找小于等于最大高度的值,所以输出l)
细节:注意无法制作出月饼,即输出-1的情况。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 1e5 + 9;
ll a[maxn];
bool check(ll x, ll k, ll n){
ll num = 0;
for (int i = 1; i <= n; i++) num += a[i] / x;
if (num >= k) return true;
else return false;
}
int main()
{
ll n, k; cin >> n >> k;
ll sum = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
sum += a[i];
}
if (sum < k) {
cout << -1;
return 0;
}
ll l = 1, r = 1e9 + 9;
while (l + 1 < r){
ll mid = (l + r) / 2;
if (check(mid, k, n)) l = mid;
else r = mid;
}
cout << l;
return 0;
}