二分查找是一个非常主要的算法,针对的是有序的数列,通过中间值的大小来推断接下来查找的是左半段还是右半段,直到中间值的大小等于要找到的数时或者中间值满足一定的条件就返回,所以当有些问题要求在一定范围内找到一个满足一些约束的值时就能够用二分查找,时间复杂度O(log n);
题目:http://acm.hit.edu.cn/hoj/problem/view?id=2651
由于题目有精度要求,对于浮点数小数点部分会有一定误差,所以能够选择将这些有小数部分的数值扩大e6倍,由于题目要求精确到e-3,之后结果在依照要求缩小即可
#include <iostream> #include <cstdio> #include <cmath> #define pi 3.14159265358979 #define MAX 10010 using namespace std; long long size[MAX]; int c,n,f; bool judge(long long x) { long long m = 0; for(int i = 0;i < n;i++){ m += size[i] / x; } return m >= f; } int main() { long long high,mid,low,res; int a; cin>>c; while(c --){ cin>>n>>f; f += 1; low = 0; high = 0; res = 0; a = 0; for(int i = 0;i < n;i++){ cin>>a; size[i] = a*a*pi*1000000; high += size[i]; } while(low <= high){ mid = (low + high)/2; if(judge(mid)){ low = mid+1; res = mid; } else high = mid-1; } printf("%.4lf ",(double)res/1000000); } return 0; }