题目描述:
有 n 条绳子,它们的长度分别为 Li,如果从它们中切割出 m 条长度相同的绳子,这 m 条绳子每条最长能有多长?
输入格式:
第一行两个整数 n和 m。
接下来 n行,每行一个实数,描述了每条绳子的长度 Li。
数据范围:1<=n<m<=10000;1<=Li<=100000.
输出格式:
切割后每条绳子的最大长度,保留 6位小数。
实例:
输入:
4 11 8.02 7.43 4.57 5.39
输出:
2.00
解题思路:
从n条绳子里切割,最长切割出来也应该是n条中最长的那个max,所以根据二分的思想,切割后每条绳子的左右边界分别是0,max。然后根据这个先取一个假定的mid,在区间里找到能满足切割条数为m的最大长度。
参考代码:
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1001;
double a[N];
int n, m;
double ans;
int check(int k)
{
int count = 0;
for(int i=0;i<n;i++)
{
count += a[i] / k;//这个绳长可以得到几个
}
if (count>=m)//如果可以达到需求
return 1;
else
return 0;
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)
{
double t;
cin >> t;
a[i] = 100 * t;//将绳长都变成整数值,结果除以100.0即可
}
sort(a, a + n);
int l = 0, r = a[n-1];//右边界为绳长最长的那一根绳子,这样如果他只要一根最长的满足即可
while(l<=r)
{
int mid = (l + r) / 2;//猜测的切绳子长度
if (check(mid))
{
//ans = mid;
l = mid + 1;//说明绳长可以再加,在区间右侧
}
else
r = mid - 1;//说明绳太长,不能满足需求量
}
printf("%.6lf", r/100.0);
return 0;
}