题解 UVA10566 Crossed Ladders

题目大意

给出两把梯子的高长度 $x$ 和 $y$,以及交叉点 $c$ 的高度,求道路的宽(即两梯子底端之间的距离)。

解题思路

数学 + 二分

可以利用梯子的长度和梯子与地面的夹角来求得道路的宽。

设梯子 $x$ 与 $y$ 与地面的夹角分别为 $\alpha$ 和 $\beta$,道路的宽设为 $w$,梯子 $x$ 的底端与交叉点在地面的水平投影距离为 $h$。

则有 $\sin(\alpha)=\frac{c}{x}$,$\sin(\beta)=\frac{c}{y}$,$\cos(\alpha)=\frac{w+h}{x}$,$\cos(\beta)=\frac{w}{y}$。

解出 $h$ 为:
$\displaystyle h=y\times\cos(\beta)=y\times\sqrt{1-\sin^2(\beta)}=y\times\sqrt{1-\frac{c^2}{y^2}}=y\times\frac{\sqrt{y^2-c^2}}{y}=\sqrt{y^2-c^2}$
并表示道路宽 $w$ 为:
$\displaystyle w=x\times\cos(\alpha)-h=x\times\sqrt{1-\sin^2(\alpha)}-h=x\times\sqrt{1-\frac{c^2}{x^2}}-h=x\times\frac{\sqrt{x^2-c^2}}{x}-h=\sqrt{x^2-c^2}-h$
将 $h=\sqrt{y^2-c^2}$ 代入,得:
$\displaystyle w=\sqrt{x^2-c^2}-\sqrt{y^2-c^2}$
不难看出,该解析式具有单调递减性,又由于数据为实数,则可以使用实数二分,不断逼近所需精度。

代码

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#define int long long
#define endl "\n" 
using namespace __gnu_cxx;
using namespace __gnu_pbds;
using namespace std;
double x,y,c;
inline bool check(long double m)//检查函数
{
    long double h1=sqrt(x*x-m*m);
    long double h2=sqrt(y*y-m*m);
    return (h1*h2)<(h1*c+h2*c);//返回精度偏小(true)还是偏大(false)。
}
signed main() 
{
    while(cin>>x>>y>>c)
    {
        long double l=0,r=min(x,y);//左右端点
        long double m;
        while(r-l>=1e-6)//实数二分
        {
            m=(l+r)/2;//注意 double 类型不能用右移运算
            if(check(m))r=m;
            else l=m;
        }
        cout<<fixed<<setprecision(3)<<l<<endl;
    }
    return 0;
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇