题意:有N条绳子,它们的长度分别为Li。如果从它们中切割出K条长度相同的绳子的话,这K条绳子最长能有多长?答案保留到小数点后2位。
思路:这些最大最小化问题大多数可以用二分查找的方法来解题
用 d 表示绳子最长可以为d,然后循环利用二分搜索使得中间值不断地缩小直到到达想要的精度
就是
void solve() { int low=0; int high=INF; for(int i=0;i<100;i++){ int mid=(low+high)/2; if (is_ok(mid)) low=mid; else high=mid; } printf("%.2f ",floor(high*100)/100); }
下面是完整的代码
#include<iostream> #include<cstdio> #include<cmath> using namespace std; int K,N; const int INF=99999; double line[10001]; bool is_ok(double x)//用来判断这个值是否能使条件成立 { int num=0; for(int i=0;i<N;i++) { num+=(int)(line[i]/x); } return num>=K; } void solve() { double low=0; double high=INF; for(int i=0;i<100;i++) { /* 这个思想是二分查找, 这是利用二分查找不断地是条件精确到需要的地步 就像用100次的循环就是使mid的值不断地缩小 从而找出相对精确的中间值很巧妙 */ double mid=(low+high)/2; if(is_ok(mid)) low=mid; else high=mid; } printf("%.2f ",floor(high*100)/100); } int main() { while(cin>>N>>K) { for(int i=0;i<N;i++) cin>>line[i]; solve(); } return 0; }