分饼 二分

本文介绍了一个算法问题,即如何在给定多个不同大小的圆形蛋糕时,通过计算找到能够为指定数量的人提供最大且等量蛋糕份额的方法。该算法使用了二分查找技术来确定每个人可以得到的最大蛋糕体积。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

My birthday is coming up and traditionally I'm serving pie. Not just one pie, no, I have a number N of them, of various tastes and of various sizes. F of my friends are coming to my party and each of them gets a piece of pie. This should be one piece of one pie, not several small pieces since that looks messy. This piece can be one whole pie though.

My friends are very annoying and if one of them gets a bigger piece than the others, they start complaining. Therefore all of them should get equally sized (but not necessarily equally shaped) pieces, even if this leads to some pie getting spoiled (which is better than spoiling the party). Of course, I want a piece of pie for myself too, and that piece should also be of the same size.

What is the largest possible piece size all of us can get? All the pies are cylindrical in shape and they all have the same height 1, but the radii of the pies can be different.

 

Input

One line with a positive integer: the number of test cases. Then for each test case:
---One line with two integers N and F with 1 <= N, F <= 10 000: the number of pies and the number of friends.
---One line with N integers ri with 1 <= ri <= 10 000: the radii of the pies.

Output

For each test case, output one line with the largest possible volume V such that me and my friends can all get a pie piece of size V. The answer should be given as a floating point number with an absolute error of at most 10^(-3).

Sample Input

3
3 3
4 3 3
1 24
5
10 5
1 4 2 3 4 5 6 5 4 2

Sample Output

25.1327
3.1416
50.2655

 

 

 

#include<stdio.h>
#include<algorithm>
#include<math.h>
using namespace std;
#define PI acos(-1.0)
int main()
{
    int n;
    int x,y;
    int a[99999];
    int i,j;
    double r,l,mid;
    scanf("%d",&n);
    while(n--){
        scanf("%d %d",&x,&y);
        for(i=0;i<x;i++)
            scanf("%d",&a[i]);
        sort(a,a+x);
        r=a[x-1]*a[x-1];//找出半径最大的 相乘

        l=0;
        while(r-l>1e-6)//二分找出合适的
        {
            mid=(l+r)/2;
            int sum=0;
            for(i=0;i<x;i++)
            {
                sum=sum+(a[i]*a[i]/mid);//看看数量是否足够
            }
            if(sum>=(y+1))
                l=mid;
            if(sum<(y+1))
                r=mid;

        }
            printf("%.4lf\n",r*PI);
         //int a[99999]={0};
    }

    return 0;
}

 

 

 

### 贪心算法解决干问题 #### 解题思路 贪心算法的核心在于每一步都做出局部最优的选择,期望最终达到全局最优的结果。对于干问题,目标是通过配尽可能小的干来满足尽可能多的孩子。因此,可以通过以下方法解决问题: 1. **排序**:别对孩子胃口值 `g` 和干尺寸 `s` 进行升序排序[^3]。 2. **双指针遍历**:使用两个指针别指向孩子和干列表的起始位置。每次尝试用最小的可用干去满足具有最小胃口的孩子。 3. **匹配逻辑**:如果当前干能够满足当前孩子的胃口,则将两者的指针均向右移动;否则仅移动干指针。 这种方法的时间复杂度主要由排序决定,为 \(O(n \log n)\)[^4]。 #### Python 实现代码 以下是基于上述思路编写的 Python 代码示例: ```python def findContentChildren(g: list, s: list) -> int: # 对孩子们的胃口值和干尺寸进行升序排序 g.sort() s.sort() child = 0 # 初始化孩子索引 cookie = 0 # 初始化干索引 satisfied_children = 0 # 记录已满足的孩子数量 # 遍历直到其中一个列表结束 while child < len(g) and cookie < len(s): if g[child] <= s[cookie]: # 如果当前干能喂饱当前孩子 satisfied_children += 1 # 增加计数器 child += 1 # 移动到下一个孩子 cookie += 1 # 不管是否满足,都需要尝试下一枚干 return satisfied_children # 返回满足的孩子总数 ``` 调用此函数的一个实例如下所示: ```python print(findContentChildren([1, 2, 3], [1, 1])) # 输出结果应为 1 ``` #### 示例解析 假设输入参数为 `g = [1, 2, 3]` 和 `s = [1, 1]`,则执行流程如下: 1. 排序后的 `g` 和 `s` 别为 `[1, 2, 3]` 和 `[1, 1]`。 2. 使用第一个干(大小为 1)满足第一个孩子(胃口为 1),此时 `satisfied_children = 1`。 3. 第二个干无法满足第二个孩子(因为其胃口大于干尺寸),循环终止。 4. 最终返回结果为 `1` 表明只有一个孩子得到了满足。 #### 结论 以上代码实现了利用贪心算法解决干问题的功能,并且遵循了贪心策略的原则——优先考虑较小需求与资源之间的最佳匹配[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值