分析
由于这题如果长的绳子可以是答案,那么肯定较短的绳子也可以
也就是说具有单调性,所以就可以用二分,这里结果保留小数点两位
哪么就是小数二分。下界是0,上界是最大的ai 我这里先大到小排序的原因是因为
便于ok函数更快地检测出可行性,因为长的绳子更容易剪出多个小绳子,然后这里的精度是0.001
因为结果保留两位小数,那么0.001差不多够了。如果精度过低导致有的极端数据二分次数过多
复杂度就更高。
时间复杂度
$O(Nlog(N))$
C++ 代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int a[N];
int n,m;
bool cmp(int x,int y)
{
return x > y;
}
bool ok(double x)
{
int cnt = 0;
for(int i = 1;i <= n;i++)
{
cnt += int(a[i]/x);
if(cnt >= m) return 1;
}
return 0;
}
int main()
{
scanf("%d%d",&n,&m);
double l = 0,r = 0;
for(int i = 1;i <= n;i++)
{
scanf("%d",&a[i]);
r = max(1.0*a[i],r);
}
sort(a+1,a+n+1,cmp);
// cout << l << " " << r << endl;
// for(int i = 1;i <= n;i++)
// cout << a[i] << " ";
// cout << endl;
while((l+0.001) < r)
{
double mid = (l + r)/2;
//cout << mid << " " << ok(mid) << endl;
if(ok(mid))
l = mid;
else r = mid;
}
printf("%.2f\n",l);
return 0;
}