题目背景
mxj买了n个长条形面包,但是他们的长度不完全相同,为了让俱乐部的每个孩子得到长度相同并且尽可能能长的面包,mxj开始敲起了代码,计算如何切面包。
题目描述
这n个面包的长度至少为1,俱乐部中现在有k个人,现在你需要计算出如何把这n块面包切成k块,并使这k块面包的长度最大?保证答案有解,答案保留两位小数。
输入格式:
第一行,两个整数n,k,意义如上
第二行有n个数,表示每条面包的长度Li,每个输入都有两位小数.
输出格式:
输出面包的最大长度(保留2位小数)
输入样例#1:
4 11
8.02
7.43
4.57
5.39
输出样例#1:
2.01
说明
1<=n,k<=10000
1<=Li<=100000
代码及解释
#include<cstdio>
int main()
{
double arr[10005];
int n,k;
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++)
scanf("%lf",&arr[i]);
double mi=0,ma=1000000,mid;
while(ma-mi>1e-3) //确定结束二分的条件可以用for(int j=0;j<30;j++)代替。
//以上for循环中30的意思是2^30^>1000000/0.01,即确定精度。
{
double sum=0; //用sum表示估测答案可以切出的面包树。
mid=(mi+ma)/2.0;
for(int i=0;i<n;i++) //用sum加上每条面包可以切成的块数。
sum+=(int)(arr[i]/mid);
if(sum>=k)mi=mid; //缩小二分的范围。
else ma=mid;
}
printf("%.2lf\n",ma);
return 0;
}
二分试用范围
辣么,遇到什么类型的题要想二分呢?
当估测一个答案的正确性比求解一个答案简单时,可以考虑二分求解。