UESTC1722(二分)

越快越好!

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
 

假期将至,潘警长打算带n个实习步行出去巡逻,他们正通过一条长l米的通道。每个见习的速度恒定为v1米每秒。

为了尽快通过这条通道,大家向总部请求了一辆巡逻车。巡逻车可以载k个人(即一次不能运超过k个人)而且速度恒定为v2米每秒。

因为吃苦耐劳是我们的传统,所以每个人只能乘一次巡逻车。

现在请求出所有人通过通道的最小时间,忽略上下车的时间和车子掉头的时间。

什么?你问我警长算不算?他开车呢,故不计入上述n和k中。

Input

输入包含多组数据(组数不超过50),每组数据仅一行五个整数n,l,v1,v2和k,含义见题目描述。

变量满足如下约定:1<=n<=10000,1<=l<=10^9,1<=v1<v2<=10^9,1<=k<=n

Output

一个实数表示最小时间,要求与答案的相对误差在10-6以内。

Sample input and output

Sample Input Sample Output
5 10 1 2 5
3 6 1 2 1
5.0000000000
4.7142857143

Hint

by litter_star

Source

2017 UESTC Training for Math

解题思路:我们首先二分答案,我们可以发现,每个人走的路分为两种,一种是他自己步行,一种是他坐车,显然最优解肯定是每个人的坐车时间和步行时间

一样(每个人坐车情况一样,不要误认为坐车的时间和步行时间一样都为总时间的1/2),既然这样那么判断一个时间是否合法,直接模拟一遍就行,因为一旦总时间确定,我们可以计算出坐车的时间和步行的时间,最后有一点要注意车也要回到终点,刚开始没有注意到这个,wa了无数发。


#include <bits/stdc++.h>
using namespace std;
int n, k;
double l, v1, v2;
double eps = 1e-6;
bool judge(double mid)
{
    double x = (v1 * v2 * mid - v2 * l) / (v1 - v2);
    double t1 = x / v2;
    double t2 = (x - v1 * t1) / (v1 + v2);
    double x1 = x - v2 * t2;
    double now = 0;
    double sum = 0;
    if(n % k == 0)
    {
        int num = n / k;
        sum = (double)num * (t1 + t2);
        sum -= t2;
        now += (num - 1) * x1;
        now += x;
    }
    else
    {
        int num = n / k;
        sum = (double) num * (t1 + t2);
        sum += t1;
        now += num * x1;
        now += x;
    }
    if(sum - mid > eps) return false;
    double dd = mid - sum;
    now += dd * v2;
    if(now - l >= eps) return true;
    else return false;
}
int main()
{
    while(~scanf("%d%lf%lf%lf%d", &n, &l, &v1, &v2, &k))
    {
        double L = l / v2;
        double R = l / v1;
        while(R - L > eps)
        {
            double mid = (L + R) / 2.0;
            if(judge(mid))
            {
                R = mid;
            }
            else
            {
                L = mid;
            }
        }
        printf("%.10lf\n", L);
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值