为自己没有学过奥数流下了悔恨的泪水>_<
下面是题目复述:
题目描述:
甲、乙两人同时从 A 地出发要尽快同时赶到 B 地。出发时 A 地有一辆小车,可是这辆小车除了驾驶员外只能带一人。已知甲、乙两人的步行速度一样,且小于车的速度。问:怎样利用小车才能使两人尽快同时到达。
输入格式:
仅一行,三个整数,分别表示 A、B 两地的距离s (1≤s≤2000) 米,人的步行速度 a 米/秒,车的速度 b 米/秒,a<b<2000。
输出格式:
两人同时到达 B 地需要的最短时间,单位秒,保留 2 位小数。
Sample Input
120 5 25
Sample Output
9.60
分析过程:
- 首先,对题目进行分析,研究一下所有数据之间的关系,然后发现只有在人坐车时间最长而且两个人同时出发同时到达的时候时间最短,所以可以把这两个过程当做二分的变量和check的条件。
- 假设第一个人a下车的地方为k。此时,a下车之后时间为k/b,他可以一直向前走,直到B地,小车从k处返回,去接仍在路上的b。这样就可以算出a的运动时间是k/b+(s-k)/a。
注意: 虽然当两人可以看出两人运动路程对称相等的时候人走路的时间最短,但是此时b还未走到s-k处,b走到s-k处应当是在小车回去之后。
- 人b此时走的路程是a* (k/b),此时离小车来接他还有k-(k/b)* a的距离,这时候一人一车属于相向而行,所以计算过程是(k-(k/b)* a)/(a+b)。
- 最后,b剩余的距离为s减去第一阶段运动距离(k/b)* a,第二阶段运动距离(s-((k-(k/b)* a)/(a+b)* a,然后除车速就可以计算出来第三阶段的时间k/b+(k-(k/b)* a)/(a+b)+(s-((k-(k/b)* a)/(a+b)* a+((k/b)* a)))/b了。
下面是AC代码:
#include <iostream>
#include <cstdio>
#include <climits>
#include <cmath>
//本题,两人运动时间相等即为成功
using namespace std;
double s,a,b;
double ti,k;
double t1,t2;
bool check (double k)
{
t1=k/b+(s-k)/a;
t2=k/b+(k-(k/b)*a)/(a+b)+(s-((k-(k/b)*a)/(a+b)*a+((k/b)*a)))/b;
if(t1<t2)//
return true;
return false;
}
double bsearch(double l,double r)//以人下车的位置为分界点
{
while (fabs(r-l)>1e-8)
{
double mid=(l+r)/2;
if(check(mid)) r=mid;
else l=mid;
}
return l;
}
int main()
{
scanf("%lf %lf %lf",&s,&a,&b);
ti=bsearch(0,s);
printf("%.2f\n",t1);
return 0;
}