分析:一輛車最多載k個人,車的速度肯定比人快,所以想要到達時間最短,那麼每個人必須做一次公交車。那麼把n個人分成p=(n+k-1)/k組。設最短時間為t,每人乘車時間為t1,則t1*v2+(t-t1)*v1=L。設每次車子返回走的時間為t2,則(t1+t2)*v1+t2*v2=t1*v2。由這兩個式子可以寫出t1,t2的表達式。又因為p*t1+(p-1)*t2=t. 所以可以以最短時間L/v2為左端值,以L/v1為右端值二分t。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; int n,k; double l,v1,v2; int solve(double t,int p) { double t1=(l-t*v1)/(v2-v1); double t2=(v2-v1)*t1/(v1+v2); double ans=t1*p+t2*(p-1); if(ans<t) return 1; return 0; } int main() { scanf("%d%lf%lf%lf%d",&n,&l,&v1,&v2,&k); int p=(n+k-1)/k; double low=l/v2,high=l/v1; double mid=(low+high)/2; while(high-low>0.000001) { int ret=solve(mid,p); if(ret==1) high=mid; else low=mid; mid=(low+high)/2;//這個地方竟然坑了我一把,如果把這一行放置while循環的第一個語句,結果wa了。。。 } printf("%.10lf\n",mid); return 0; }
但是,為什麼要用二分呢,就是因為cf上面有二分這個標簽嘛?明擺著t=p*t1+(p-1)*t2. 所以可以直接求解啊!
#include <cstdio> #include <cstring> int main() { int n,k; double v1,v2,l; scanf("%d%lf%lf%lf%d",&n,&l,&v1,&v2,&k); int p=(n+k-1)/k; double a=l*p/(v2-v1)+l*(p-1)/(v1+v2); double b=v1*p/(v2-v1)+v1*(p-1)/(v1+v2)+1; printf("%.10lf\n",a/b); return 0; }