ICPC Northwestern European Regional Programming Contest B Bottle Flip

ICPC Northwestern European Regional Programming Contest B Bottle Flip

题意:

给你一个高度为 H H H ,半径为 r r r的水杯,并告诉你空气密度 ρ a \rho_{a} ρa和水的密度 ρ w \rho_{w} ρw,求使得整个杯子装水后质心最低的水量

大致思路:

前置物理知识:如果处理多个部分的重心比较困难,但整体处理比较简单时,我们可以将求出这一部分物体的质心和质量,这两部分在处理整个物体的质心时时等价的。

即若把物体分成 a , b a,b a,b两个部分有:
X = ∑ i = 0 k x i m i ∑ i = 1 k m i X a = ∑ i = 1 k a x i m i ∑ i = 1 k a m i X b = ∑ i = 1 k b x i m i ∑ i = 1 k b m i M a = ∑ i = 1 k a m i M b = ∑ i = 1 k b m i X = X a M a + X b M b M a + M b X=\frac{\sum_{i=0}^k x_{i}m_{i}}{\sum_{i=1}^k m_{i}}\\ X_{a}={{\sum_{i=1}^{k_a} x_i m_i}\over \sum_{i=1}^{k_a} m_i}\\ X_{b}={{\sum_{i=1}^{k_b} x_i m_i}\over \sum_{i=1}^{k_b} m_i}\\ M_a=\sum_{i=1}^{k_a} m_i\\ M_b=\sum_{i=1}^{k_b} m_i\\ X={X_aM_a+X_bM_b\over M_a+M_b} X=i=1kmii=0kximiXa=i=1kamii=1kaximiXb=i=1kbmii=1kbximiMa=i=1kamiMb=i=1kbmiX=Ma+MbXaMa+XbMb
我们设水的高度为 h h h,那么重心高度则有
X w ( h ) = h 2 X a ( h ) = H + h 2 M a ( h ) = S ( H − h ) ρ a M w ( h ) = S h ρ w X ( h ) = 1 2 ( S h 2 ρ w + ( H 2 − h 2 ) ρ a ) S ( H − h ) ρ a + S h ρ w = 1 2 ( h 2 ρ w + ( H 2 − h 2 ) ρ a ) ( H − h ) ρ a + h ρ w X_w(h)= {h\over 2}\\ X_a(h)={H+h \over 2}\\ M_a(h)= S(H-h)\rho_a\\ M_w(h)=Sh\rho_w\\ X(h)=\frac{{1 \over 2} (Sh^2 \rho_w+(H^2-h^2) \rho_a)}{S(H-h)\rho_a+Sh\rho_w}= {1 \over 2}\frac{ (h^2 \rho_w+(H^2-h^2) \rho_a)}{(H-h)\rho_a+h\rho_w} Xw(h)=2hXa(h)=2H+hMa(h)=S(Hh)ρaMw(h)=ShρwX(h)=S(Hh)ρa+Shρw21(Sh2ρw+(H2h2)ρa)=21(Hh)ρa+hρw(h2ρw+(H2h2)ρa)
数学较好的同学可以将 X ( h ) X(h) X(h) h h h 求导。

另外,我们可以发现 X ( h ) X(h) X(h) 是一个单峰函数,故三分可以通过本题

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long int
double H, y, Pa, Pw;
double eps = 1e-10;
double check(double h)
{
    double a1 = (h * h * Pw + (H * H - h * h) * Pa) * 0.5;
    double w = h * Pw + (H - h) * Pa;
    return a1 / w;
}
signed main()
{
    cin >> H >> y >> Pa >> Pw;
    double l = 0, r = H;
    while (r - l >= eps)
    {
        double midl, midr;
        midl = l + (r - l) / 3;
        midr = r - (r - l) / 3;
        if (check(midl) > check(midr))
            l = midl;
        else
            r = midr;
    }

    cout << fixed << setprecision(10) << l << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值