贪心 - poj3122 Pie

来源:互联网 发布:加入淘宝客的要求 编辑:程序博客网 时间:2024/06/06 02:44

题目:

http://poj.org/problem?id=3122


题意:

F+1个人分N个派,派可以切分但是每个人只能得到一块派,每个人得到的派体积必须相同,问最大可分体积


思路:

二分+贪心,最大可分的体积为最大派的体积,最小可分为0,二分遍历即可

这道题比较坑的地方在于要注意PI的精度,虽然题目只要求到3位小数,但是PI使用3.1415926会出错,这种常数精度应该尽量取高


代码:

#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<math.h>#include<algorithm>#include<vector>#include<queue>#include<stack>#include<map>#include<set>#include<functional>#include<iomanip>//#pragma comment(linker, "/STACK:102400000,102400000")//C++using namespace std;const int MAXINT = 0x7fffffff;const int MAXSIZE = 10000 + 5;const double PI = 3.141592653589793238462643383279502884197169399;int main(){    int total;    cin>>total;    double pie[MAXSIZE];    while (total--){        int n,f;        double high=0,low=0;        memset(pie,sizeof(pie),0);        cin>>n>>f;        for (int i=0;i<n;++i){            int a;            cin>>a;            pie[i]=a*a*PI;            if (high<pie[i]) high=pie[i];        }        //cout<<"low "<<low<<" high "<<high<<endl;        double ans;        while (fabs(high-low)>1e-5){            double mid=(high+low)/2;            //cout<<"low "<<low<<" high "<<high<<" mid "<<mid<<endl;            //cout<<fabs(high-low)<<endl;            //getchar();            int sum=0;            for (int i=0;i<n;++i){                sum+=(int)(pie[i]*1.0/mid);            }            if (sum>=f+1){                ans=mid;                low=mid;            }            else {                high=mid;            }        }        //cout<<setiosflags(ios::fixed);        //cout<<setprecision(4)<<ans<<endl;        printf("%.4lf\n",ans);    }    return 0;}


0 0