题目链接:
OpenJudge - 04:网线主管http://noi.openjudge.cn/ch0111/04/
又是一道浮点数二分转整数二分的题。总结:浮点数二分尽量避免,尤其是精度不高(比如两位小数)的时候 ,优先考虑转成整数处理。
代码:
一开始wa了的浮点数二分写法
#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-6;
const int maxn = 1e5+5;
double len[maxn];
int n, k;
bool check(double mid){
int count = 0;
for(int i=1; i<=n; i++){
count += len[i]/mid;
}
return count >= k;
}
int main(){
cin >> n >> k;
double maxLen = 0;
for(int i=1; i<=n; i++){
cin >> len[i];
maxLen = max(maxLen, len[i]);
}
double left = 0.01, right = maxLen;
if(!check(0.01)) {cout<<"0.00"<<'\n'; return 0;}
double ans = 0.01;
while(right - left >= eps){
double mid = left + (right-left)/2;
if(check(mid)) {left = mid; ans = mid;}
else right = mid;
}
printf("%.2f\n", ans);
}
之后转成整数的ac代码:
#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-6;
const int maxn = 1e5+5;
int len[maxn];
int n, k;
bool check(int mid){
int count = 0;
for(int i=1; i<=n; i++){
count += len[i]/mid;
}
return count >= k;
}
int main(){
cin >> n >> k;
int maxLen = 0;
for(int i=1; i<=n; i++){
double tmp; cin >> tmp;
len[i] = tmp*100;
maxLen = max(len[i], maxLen);
}
int ans = 0;
int left = 1, right = maxLen;
while(left <= right){
int mid = left+(right-left)/2;
if(check(mid)) {left = mid+1; ans = mid;}
else right = mid-1;
}
double res = (double)ans/100;
printf("%.2f\n", res);
}