Problem C: Pie

时间:2022-05-23 04:06:48

题目链接

http://codeforces.com/gym/100722/attachments/download/3466/20062007-northwestern-european-regional-contest-nwerc-2006-en.pdf

题目大意

你要过生日了,有n个派,来了f个朋友,每个派的半径是ri,分给每人一块等大的派,使每块派的面积最大

分析

我们不难发现,这是一个很明显的二分答案题。我们再计算时不妨带进ri的平方,最后再乘π

但有两个需要注意的点:

一  派的半径、下限、上限、mid都要用double(用int会wa2)

二  初始上限应定为所有派的面积总和/f+1,下限应定为最大的一个派的面积/f+1(定别也可以,例如把上限定为最大的一个派的面积下限定为0.000001(但如果下限定为1就会wa2)。不过按第一种定会跑得快一些)

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define pi acos(-1.0)
double r[100100];
int main()
{     int t,p,i,j,k,n,f;
      scanf("%d",&t);
      for(p=1;p<=t;p++){
          scanf("%d%d",&n,&f);
          f+=1;
          double lb=-1,ub=0;
          for(i=1;i<=n;i++){
              scanf("%lf",&r[i]);
              r[i]*=r[i];
              lb=max(lb,r[i]);
              //ub+=r[i];
          }
          ub=lb;
          lb/=f;
          double mid;
          while(lb+0.00001<ub){
              mid=(lb+ub)/2;
              double sum=0;
              for(i=1;i<=n;i++){
                 sum+=(int)(r[i]/mid);
                 if(sum>f)break;
              }
              if(sum>=f){
                  lb=mid;
              }
                else if(sum<f){
                    ub=mid;
                }
          }
          printf("%0.4lf\n",lb*pi);
      }
      return 0;
}