7-5 派 (15 分)

7-5 派 (15 分)

我的生日要到了!根据习俗,我需要将一些派分给大家。我有N个不同口味、不同大小的派。有F个朋友会来参加我的派对,每个人会拿到一块派(必须一个派的一块,不能由几个派的小块拼成;可以是一整个派)。

我的朋友们都特别小气,如果有人拿到更大的一块,就会开始抱怨。因此所有人拿到的派是同样大小的(但不需要是同样形状的),虽然这样有些派会被浪费,但总比搞砸整个派对好。当然,我也要给自己留一块,而这一块也要和其他人的同样大小。

请问我们每个人拿到的派最大是多少?每个派都是一个高为1,半径不等的圆柱体。

输入格式:

第一行包含两个正整数N和F,1 ≤ N, F ≤ 10 000,表示派的数量和朋友的数量。 第二行包含N个1到10000之间的整数,表示每个派的半径。

输出格式:

输出每个人能得到的最大的派的体积,精确到小数点后三位。

输入样例:

3 3
4 3 3结尾无空行

输出样例:

在这里给出相应的输出。例如:

25.133



结尾无空行
#include <iostream>
#include <math.h>
#define PI 3.1415926535898
using namespace std;

double volume(double r)
{
    return PI * r * r;
}

int main()
{
    int N; //派的数量
    int F; //朋友的数量
    cin >> N;
    cin >> F;

    double *pai = new double[N];
    double r;        //派的半径
    double maxV = 0; //最大体积
    //循环存入派的体积
    for (int i = 0; i < N; i++)
    {
        cin >> r;           //获取一个半径
        pai[i] = volume(r); //计算派的体积并存入
        if (pai[i] > maxV)  //记录pai的最大值
        {
            maxV = pai[i];
        }
    }

    //用类似极限的方法逼近那个可以满足的最大值
    double left, right; //定义左右指针
    double mid;         //中值
    left = 0;
    right = maxV;
    while (right - left > pow(10, -7))
    {
        mid = (left + right) / 2; //获得体积中值
        int sum = 0;              //记录每块饼能分出的最多块数
        for (int i = 0; i < N; i++)
        {
            sum += (int)(pai[i] / mid);
        }

        if (sum > F) //当饼够人分时,说明可能还可以再分大一点  取体积区域的右半[mid,r]
        {
            left = mid;
        }
        else //当饼不够分时,说明划分区域太大了 取体积区域的左半[l,mid]
        {
            right = mid;
        }
    }
    //当跳出循环时,说明已经处于能分的最大值
    printf("%.3f", mid);
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值