Description
TheBeet正在参加一场越野车大赛。比赛的场地如右图:共分三块,每一块地面的长宽均为N与M,但地表情况不同,越野车在这段路面上的最高速度也不同。蓝色线表示TheBeet可能的行车路线。
比赛的要求是要求选手从比赛的场地左上角驾车至右下角。TheBeet想知道如果他在所有路段都以最快速度行驶(不考虑加速阶段),最快能在多少时间内完成比赛。
Input
输入数据的第一行为两个正整数N M(N<=3000,M<=1000),表示一块路面的长和宽。
第二行为三个正整数S1,S2,S3(0<S1,S2,S3<=100),从上至下依次表示各个路面上越野车的最高速度。
Output
输出一个实数表示TheBeet最快能在多少时间内完成比赛。请输出一个尽可能精确的数字,控制误差在±0.000001的内。
Sample Input
30 10
2 5 3
Sample Output
13.7427361525
Hint
如果你的输出和结果的相差在0.000001之内,则认为是正确答案。
思路:
这个题目不错。横线N上有两个点,先要确定第一个x1,x1可能为mid1或midmid1;1,以mid1为基准求第二个点 2,以midmid1为基准求第二个点。比较两个结果再一次三分求极值。
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define eps 1e-7 int n,m; int s1,s2,s3; double cal(double x,double y) { return sqrt(m*m+x*x)/s1+sqrt(m*m+y*y)/s2+sqrt(m*m+(n-x-y)*(n-x-y))/s3; } int main() { cin>>n>>m; cin>>s1>>s2>>s3; double ans=0xfffffff; double l=0,h=n,ll=0,hh=n; double mid1,midmid1,mid2,midmid2; double t1,t2,t11,t22; while(h-l>eps) { mid1=(l+h)/2; midmid1=(mid1+h)/2; //ans1=cal(mid1); //ans11=cal(midmid1); ll=0,hh=n; while(hh-ll>eps) { mid2=(ll+hh)/2; midmid2=(mid2+hh)/2; t11=cal(mid1,mid2); t22=cal(mid1,midmid2); if(t11<t22) hh=midmid2; else ll=mid2; }//计算mid1为基准的第二个点的位置 t1=cal(mid1,ll); ll=0,hh=n; while(hh-ll>eps) { mid2=(ll+hh)/2; midmid2=(mid2+hh)/2; t11=cal(midmid1,mid2); t22=cal(midmid1,midmid2); if(t11<t22) hh=midmid2; else ll=mid2; } t2=cal(midmid1,ll); if(t1<t2) { h=midmid1;ans=min(ans,t1); } else { l=mid1;ans=min(ans,t2); } } printf("%.10lf\n",ans); return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/kaisa158/article/details/47037315