【实数三分】2021年度训练联盟热身训练赛第三场 M.Zipline

Zipline

题目大意

如图:
在这里插入图片描述给定 w , g , r , h w, g, r, h w,g,r,h,求 Cable 的最小值和最大值,要满足中间点的高度不小于 r r r

解题思路

最小值很简单,根据两边之和大于第三边,就是求两个杆顶点连线的长度。

难点是求最大值,这里的方法是三分。

要求的长度设为 f ( x ) f(x) f(x),则 f ( x ) = x 2 + ( g − r ) r + ( w − x ) 2 + ( h − r ) 2 f(x) =\sqrt {x^2+(g-r)^r}+\sqrt{(w-x)^2+(h-r)^2} f(x)=x2+(gr)r +(wx)2+(hr)2 ,其中 x ∈ ( 0 , w ) x\in(0,w) x(0,w)

f ( x ) f(x) f(x) 是一个先递减再递增的函数,则用三分求解。

参考代码

#include<stdio.h>
#include<iostream>
#include<vector>
#include<cstring>
#include<cstdio>
#include<climits>
#include<cmath>
#include<algorithm>
#include<queue>
#include<deque>
#include<map>
#include<unordered_map>
#include<set>
#include<stack>
//#define LOCAL  //提交时一定注释
#define VI vector<int>
#define eps 1e-6
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
using namespace std;
typedef long long LL;
typedef double db;
const int inf = 0x3f3f3f3f;
const LL INF = 1e18;
const int N = 1e3 + 10;
#define ls rt << 1
#define rs rt << 1 | 1
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
inline int readint() {int x; scanf("%d", &x); return x;}

db w, g, r, h;

db calmin() {
    return sqrt((h - g) * (h - g) + w * w);
}

db calma(db x) {
    return sqrt(x * x + (g - r) * (g - r)) + sqrt((w - x) * (w - x) + (h - r) * (h - r));
}
int main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
//   freopen("output.txt", "w", stdout);
#endif
    int t = readint();
    while (t--) {
        cin >> w >> g >> h >> r;
        db min = calmin();
        db l = 0, r = w;
        db mid1, mid2;
        while (r - l > eps) {
            db k = (r - l) / 3.0;
            mid1 = l + k;
            mid2 = r - k;
            if (calma(mid1) < calma(mid2)) r = mid2;
            else l = mid1;
        }
        db ma = calma(l);
        printf("%.8f %.8f\n", min, ma);
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值