题意:有N条绳子,给出它们的长度,现在要从他们中间切割出K条长度为L的绳子,问L最大可以是多少?答案保留小数点后两位。
这道题就是求一个最大的近似解,满足条件,从N条绳子中切割出K条长度为L的绳子。
(l,r]左开右闭,当mid求出来的可切割出的绳子数量刚好是K的时候,还是选择进入到区间(mid,r],因为r会不断向mid逼近,那么最后答案还是一样的。
答案保留小数点后两位,要用floor函数。因为如果直接%.2f\n输出,那么会四舍五入,int函数返回的是整型,floor返回的是浮点型。另外,int函数向0取整,floor向下取整,这个和题目没有关系。
题目中选择用循环100次的形式逼近求近似解,因为用r - l < eps的方式可能会出现问题。
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<cmath>
#define INF 100005
#define N 10005
using namespace std;
int n, k;
double l, r, mid;
double len[N];
bool ok(double x)
{
int sum = 0;
for (int i = 0; i < n; i++)
sum += int(len[i] / x);
return sum >= k;
}
int main()
{
scanf("%d%d", &n, &k);
for (int i = 0; i < n; i++) scanf("%lf", &len[i]);
l = 0;
r = INF;
for (int i = 0; i < 100; i++)
{
mid = (l + r) / 2;
if (ok(mid)) l = mid;
else r = mid;
}
printf("%.2f\n", floor(r * 100) / 100);
return 0;
}