题目链接:OpenJudge - 05:派
很典型的一道二分答案题目,首先对题目进行分析:
如果不考虑其他的条件(必须一个派的一块,不能由几个派的小块拼成;可以是一整个派),那么每个人可以分到的最大体积就是->(总体积/人数),但这里算出来的最大值可能会大于其中某个蛋糕的面积,所以需要缩小范围来查找答案
二分查找的大概思路:
这题可以将left定为0,right定为(体积之和)/人数,依次查找
再定义一个judge函数来判断这个函数是否满足条件
每一次将mid传过去,mid为体积,因为二分查找的使用条件是数据为单调的,所以不需要考虑是否为最大值,找到最后的就是最大值
judge函数用于判断蛋糕可以分到的人数,判断是否大于总人数,如果大于返回1,反之返回0。
判断条件-> count=(int)(当前蛋糕的体积/mid);算出来的就是一个蛋糕可以分的人数
最后return count>=f;即可
AC代码:
#include<iostream>
#include<math.h>
#include<stdbool.h>
#include<algorithm>
using namespace std;
#define PI acos(-1)
#define eps 1e-5
#define N 100000
double a[N];
int n, f;
bool judge(double v) {
double count = 0;
for (int i = 0; i < n; i++) {
count += (int)(a[i] / v);//每个人分到的个数,强制类型转换,去掉小数部分
}
return count >= f;//大于返回1,小于返回0;
}
int main(void) {
cin >> n >> f;
f++;//自增1,加上自己,共f+1人
double sumv = 0.0;
double R = 0.0;
for (int i = 0; i < n; i++) {
cin >> R;
a[i] = R * R * PI * 1;//计算体积
sumv += a[i];
}
double left = 0.0, right = sumv / f, mid = 0.0;
while (right - left >= eps) {
mid = (left + right) / 2;
if (judge(mid)) {
left = mid;
}
else {
right = mid;
}
}
printf("%.3lf", mid);
return 0;
}