题目来源:POJ
地址:http://noi.openjudge.cn/ch0111/05/
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
-
我的生日要到了!根据习俗,我需要将一些派分给大家。我有N个不同口味、不同大小的派。有F个朋友会来参加我的派对,每个人会拿到一块派(必须一个派的一块,不能由几个派的小块拼成;可以是一整个派)。
我的朋友们都特别小气,如果有人拿到更大的一块,就会开始抱怨。因此所有人拿到的派是同样大小的(但不需要是同样形状的),虽然这样有些派会被浪费,但总比搞砸整个派对好。当然,我也要给自己留一块,而这一块也要和其他人的同样大小。
请问我们每个人拿到的派最大是多少?每个派都是一个高为1,半径不等的圆柱体。 - 输入
- 第一行包含两个正整数N和F,1 ≤ N, F ≤ 10 000,表示派的数量和朋友的数量。
- 第二行包含N个1到10000之间的整数,表示每个派的半径。
3 3 4 3 3样例输出
25.133
题目分析
- 利用二分查找寻求最大解。
- 利用函数确定所求最大姐是否满足条件
- 注意 pi的精准度
AC代码
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const double pi=3.141592653589; const int maxn=10010; int n,f,i; int flag=0; double sum=0; double l,r,mid; double a[maxn]; double v[maxn]; int result(double m,int f,int n,double v[]) { int num=0; for (int i=n-1; i>=0; i--) { num+=(v[i]/m); } if (num<f) return 1; else return 0; }//result void swap(double &x,double &y) { double temp; temp=x; x=y; y=temp; return; }//swap int main() { cin>>n>>f; f++; for(i=0; i<n; i++) cin>>a[i]; for(i=0; i<n; i++) { v[i]=pi*a[i]*a[i]; sum+=v[i]; //总体积 正确 } sort(v,v+n); //快速排序 l=0; r=v[n-1]; mid = l-(l-r)/2; while (r-l>1e-5) { if (result(mid,f,n,v)) { r=mid; mid=l-(l-r)/2; } else { l=mid; mid=l-(l-r)/2; } } printf("%.3f\n",l); return 0; }
备注
AC码修改自同学代码,部分多余没有删除。