题目描述
有n条绳子,长度分别为L[i]。如果从他们中切割出k条长度相同的绳子的话,这k条绳子每条最长能有多长?(答案保留小数点后两位(直接舍掉两位后的小数),规定1单位长度的绳子最多可以切割成100份)
输入
包含多组输入
输入n,k,(1<=n,k<=10000)
然后n行,输入L[i],代表每一条绳子的长度(1<=L[i]<=100000)
输出
切出k条长度相等的绳子最大长度是多少,输出保留两位小数
样例输入
4 11
8.02
7.43
4.57
5.39
样例输出
2.00
解题思路:
这道题可以使用基础的二分查找代码实现,但是有一个地方必须注意,此题对于精度的要求极为严格,要特别注意。
AC代码实现:
下面这个就是没有注意细节导致错误50%
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
int i, n,k;
double a[10000];
bool check(double x) {
int i;
int s = 0;
for (i = 0; i < n; i++) {
s += a[i] / x;
}
return s >= k;
}
int main()
{
scanf("%d %d", &n, &k);
for (i = 0; i < n; i++) {
scanf("%lf", &a[i]);
}
double l = 0.00, r = 100000.00;
for (i = 0; i < 100; i++) {
double mid = (r + l) / 2;
if (check(mid))l = mid;
else
r = mid;
}
printf("%.2lf", floor(l * 100) / 100);
}
下面这个是正确的代码实现(改用C++可以更好的完成)
#include<iostream>
#include<cstdio>
using namespace std;
int n,k;
double e,a[100010];
int judge(int m)
{
int sum=0;
for(int i=1;i<=n;i++)
{
sum+=a[i]/m;
}
if(sum>=k)
return 1;
else
return 0;
}
int main()
{
while(cin>>n>>k)
{
int maxs=0;
for(int i=1;i<=n;i++)
{
scanf("%lf",&e);
a[i]=e*100;
if(maxs<a[i])
maxs=a[i];
}
int left=0,mid,right=maxs;
while(left<=right)
{
mid=(left+right)/2;
if(judge(mid))
left=mid+1;
else
right=mid-1;
}
double res=right/100.0;
printf("%.2lf\n",res);
}
return 0;
}