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