题目
(最近在备战考研,基本就不怎么碰oj了,等考完再说)
小k拥有一个神奇的蘑菇伙伴,它能够行走与说话,并且还有一个特殊的能力:当小k站到它上面时,它能够将小k弹起来,并让他在一秒内于d米距离外安全落地。换句话说,小k能够借助蘑菇在一秒时间内轻松跳跃d米远。小k非常喜爱他的这个伙伴。
一天,小k不小心错过了他上学必坐的早班车,这意味着他需要自己走到学校。这时,他想起了他的蘑菇伙伴,他可以借助蘑菇伙伴进行跳跃,在更短的时间里到达学校。
假设小k与蘑菇的行走速度分别为v1, v2,小k家到学校的路是一条直线,其长度为S。小k一次跳跃的距离为d,只有当位置重合时,小k才能够借助蘑菇起跳。小k与蘑菇一开始在同一位置,且小k最后一跳不能越过学校,否则会撞到墙上(很痛)。这意味着小k在距学校d米内不能起跳。为了赶时间,小k与蘑菇在地面上时会一直以他们的最大速度向学校行走。在起始点时小k与蘑菇在同一位置,可以进行跳跃。
本题距离单位为米,速度单位为米每秒。
……
解答
分类讨论,还挺多种情况的。
- 当s<d,小k用蘑菇会撞墙,只能自己一直走。
- 当v1>=d,小k速度比用蘑菇还快,也自己直接走。
- 当v1>=v2,小k蘑菇用完后,蘑菇追不上小k,小k之后自己一直走。
- 当v2>=d,小k蘑菇用完后,小k追不上蘑菇,小k之后自己一直走。
这些特例判断完后,就是一个追赶问题。
小k每次用完蘑菇,然后蘑菇追上小k是一个循环。
(循环中注意追赶未结束小k就到学校的情况)
#include<cstdio>
#include<cmath>
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
int main(){
double s,d,v1,v2,t;
cin>>t;
while(t--)
{
double ti=0;
cin>>s>>d>>v1>>v2;
if(s<d)
ti=s/v1;
else if(v1>=d)
ti=s/v1;
else if(v1>=v2)
ti=1+(s-d)/v1;
else if(v2>d)
ti=1+(s-d)/v1;
else{
while(s>=d)
{
s-=d;
ti+=1;
double temp=(d-v2)/(v2-v1);
if(v1*temp>=s)
{
ti+=s/v1;
s=0;
break;
}else{
s-=temp*v1;
ti+=temp;
}
}
if(s!=0)
ti+=s/v1;
}
cout<<setprecision(2)<<fixed<<ti<<endl;
}
return 0;
}
ok,所有情况都考虑了,这题就很简单了。