题目

来源:广州大学第十四届ACM大学生程序设计竞赛(同步赛)

Madeline 来到了 Golden Ridge。经过 Golden Ridge 就要注意这里的风。
Golden Ridge 的风是这样的:一开始 a 秒没有风,接下来 b 秒有向左的 x 米每秒的风,接下来 c 秒有向右的 y 米每秒的风。如此循环往复。
Golden Ridge 这段路长 m 米。Madeline 的移动速度一直是向右的 z 米每秒。实际速度是 Madeline 的移动速度与风速的矢量和。
Madeline 一开始在 Golden Ridge 的左边,求她到达 Golden Ridge 右边的时间?

解题思路

3 种风向:无风,速度为 z;向左,速度为 x-z;向右,速度为 y+z。
若 x > z,风向向左时,Madeline 倒退。

先判断 Madeline 是否能在无风时到达右边,若能,返回时间 t。
计算风的一个循环周期内,Madeline 向右走的距离为 s = a*z + b*(z-x) + c*(z+y),花费时间为 a+b+c
s <= 0,则 Madeline 永远走不到右边。
Madeline 走了 m / s 个整周期,剩下的距离就按照风向的顺序走一遍,一旦到达右边,返回时间 t。

注意输入数据使用 long long 类型。

C++代码

#include<iostream>
#include<iomanip>
using namespace std;

double getTime(long long a, long long b, long long c, long long x, long long y, long long z, long long m){
    if(a*z >= m){
        double t = 1.0*m / z;
        return t;
    }

    long long s = a*z + b*(z-x) + c*(z+y);
    if(s <= 0)
        return -1;

    double t = (m/s) * (a+b+c);
    m %= s;
    if(a*z >= m){
        t += 1.0*m / z;
        return t;
    }
    t += a;
    m -= a*z;
    if(b*(z-x) >= m){
        t += 1.0*m / (z-x);
        return t;
    }
    t += b;
    m -= b*(z-x);
    t += 1.0*m / (z+y);
    return t;
}

int main(){
    long long a, b, c, x, y, z, m;
    cin >> a >> b >> c >> x >> y >> z >> m;
    double ans = getTime(a,b,c,x,y,z,m);
    if(ans < 0)
        cout << "Badeline win" << endl;
    else
        cout << fixed << setprecision(10) << ans << endl;
    return 0;
}