思路:二分, 对莫一个长度计算总段数,计算出的总段数与题意比较,若总段数小于题目要求,长度减小,反之,长度变大
时间复杂度:O(nlogn)
#include <iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
ll a[100050];
ll n, k;
/*判断长度为len时,能否切割出k段*/
bool judge(int len)
{
ll ans = 0;
bool re = false;
/*计算满足长度len的总段数*/
for(int i = 1; i <= n; i++){
ans += a[i] / len;
}
if(ans >= k) re = true;
return re;
}
int main()
{
ll maxn = 0, sum = 0;
scanf("%lld%lld", &n, &k);
for(int i = 1; i <= n; i++){
scanf("%lld", &a[i]);
sum += a[i];
maxn = max(maxn, a[i]); /*找出长度最长的木头*/
}
ll left = 1, right = maxn; /*能切割最大长度为找到的最长木头的长度*/
while(left < right){
ll mid = (left + right)>>1;
if(judge(mid))left = mid + 1;
else right = mid - 1;
}
if(sum < k)printf("0\n");
else{
/*在小区间内进行判断*/
for(ll i = left + 5; i >= left - 5; i--){
if(judge(i)){
printf("%lld", i);
return 0;
}
}
}
return 0;
}
/*
3 7
232
124
456
*/