题目描述 Description
牛牛家有一个林场,现有 n 条木材,每条木材的长度已知且均为正整数。木材可以以任意正整数长度切割,但不可以连接。假设木材直径都一致,现有卡车可装m条木材,但是卡车长度有限,现在要从这些木材中切割出 m 条长度相同的木材,为经济效益最大化,应该选择多长的卡车,求这些木材的最大长度是多少。
输入描述 Input Description
第一行是一个不超过 100 的正整数 n。
第二行是 n 个不超过10^6的正整数,表示每条木材的长度。
第三行是一个不超过10^8的正整数 m。
输出描述 Output Description
可以切割出的木材(注:真题描述为“绳段”)的最大长度,若无法切割,输出“Failed”。
样例输入 Sample Input
3 30 20 55 4
样例输出 Sample Output
20
这道题目可以考虑用枚举的方法做,但不过枚举的方法会超时,所以我们可以优化枚举,也就是用二分来做这道题目。
先把准备工作做好
int n,m,maxn,s,ans;
int a[105];
接着,我们来写一下输入部分
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
maxn=max(maxn,a[i]);//取数组中数的最大值,r的初始值也就知道了
s+=a[i];//把所有的数组中的数累加
}
cin>>m;
接下来就是重点部分,首先我们得判断输入的m是否大于s个大于,那么就没办法切割,就可以直接输出“Failed”,同时,我们还要二分一下
if(m>s){
cout<<"Failed";
return 0;//直接结束程序
}
int l=1,r=maxn;//初始值
while(l<=r){//l<r也可以
int mid=(l+r)/2;//正常二分
if(check(mid)){
l=mid+1;
ans=mid;//记录下答案
}else{
r=mid-1;
}
}
cout<<ans;
接着就是check函数,这个比较简单
bool check(int w){
int cnt=0;
for(int i=1;i<=n;i++){
cnt+=a[i]/w;
}
return cnt>=m;
}