思路:二分答案
有 n 根木头,现在想把这些木头切割成 k 段长度均为 l 的小段木头(木头有可能有剩余)。
希望得到的小段木头越长越好,请求出 l 的最大值,
对于切出来的小段木头,长度最短是1,最长是最长的原木的长度,在这个区间进行二分答案,因为答案就在这个区间里面,对于每棵原木,用cnt加上它能切出来多少段小木头,与k进行比较,如果比k大,说明l太短了,l=mid,找右边区域;反之,如果比k小,说明l太长了,r=mid-1,找左边区域;
如果这些原木的总长度都比k小,那说明切不出来,就输出0即可;
#include<bits/stdc++.h>
#define endl "\n";
using namespace std;
typedef long long ll;
const int N=1e6+5;
typedef pair<int,int> PII;
const int INF=0x3f3f3f3f;
typedef struct node{
}node;
void IOS(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
}
//试试upper_bound(),lower_bound();
ll n,k;
void solve(){
cin>>n>>k;
vector<int>vec(n);
ll all=0;
for(int i=0;i<n;++i){
cin>>vec[i];
all+=vec[i];
}
if(all<k){
cout<<0;
}
else{
sort(vec.begin(),vec.end());
int l=1,r=vec.back();
while(l<r){
int mid=l+r+1>>1;
int cnt=0;
for(int i=0;i<n;++i){
cnt+=vec[i]/mid;
}
if(cnt>=k){
l=mid;
}
else{
r=mid-1;
}
}
cout<<l;
}
}
int main(){
IOS();
solve();
return 0;
}