[POJ 3737][三分]UmBasketella

该博客讨论了如何通过三分法解决POJ 3737问题,即给定圆锥表面积找到最大体积。文章介绍了相关数学公式,并解释了由于表面积的约束,实际问题是寻找一个开口向下的单峰函数的最大值。博主提供了问题分析和解决方案,并附上了代码。

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

题目描述:
题目链接: http://poj.org/problem?id=3737
题目大意:给定圆锥的表面积S ,求这个圆锥的最大体积V ,以及此时它的高h 与底面半径r,答案小数点后保留两位。
样例输入:
30
样例输出:
10.93
4.37
1.55
题目分析:
首先知道以下公式:
S=πrl+πr2
h=l2r2
V=13πr2h
可以看出,V 是关于r 的一个二次函数(单峰函数),因此可以三分底面半径,而确定了底面半径,又知道表面积,则其他值都可以依次计算出来,就能计算体积,三分找到最大值。
好吧,细心的同学会发现,貌似V是关于r的开口向上的二次函数,且顶点过原点,只有最小值为0,没有最大值。但实际上,因为S固定,所以h可以用S,r,π表示出来,最后其实是一个开口向下的单峰函数。推演过程如下:
l=Sπrr
h=l2r2=S2π2r22Sπ
V=13πr2h=13πr2S2π2r22Sπ=13rS22Sπr2
PS:本题多组数据。
附代码:

#include<iostream>
#include<cstring>
#include<string>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<cmath>
#include<iomanip>
#include<algorithm>
using namespace std;

const double pi=acos(-1.0);
const double eps=1e-6;
double s,l,r,mid1,mid2,rr,ll;

double find(double r)
{
    double l=(s-r*r)/r;
    double h=sqrt(l*l-r*r);
    double v=pi*r*r*h/3;
    return v;
}

int main()
{
    //freopen("lx.in","r",stdin);
    //freopen("ans1.out","w",stdout);

    while(scanf("%lf",&s)!=EOF)
    {
        s=s/pi;
        l=0;r=sqrt(s);
        while(r-l>eps)
        {
            mid1=l+(r-l)/3;mid2=r-(r-l)/3;
            double x1=find(mid1);
            double x2=find(mid2);
            if(x1<x2)
            {
                l=mid1;
                rr=mid2;
            }
            else
            {
                r=mid2;
                rr=mid1;
            }
        }
        double ll=(s-rr*rr)/rr;
        double h=sqrt(ll*ll-rr*rr);
        double v=pi*rr*rr*h/3;
        printf("%0.2f\n%0.2f\n%0.2f\n",v,h,r);
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值