您的位置:首页 > 其它

Codeforces Beta Round #5——D. Follow Traffic Rules

2015-10-06 15:08 459 查看
题意:

现在告诉你有一条道路,然后车子的加速度为a,它所能够达到的最大速度为v。

现在有一个限速的点,然后在那个点的那一瞬间你的车速不能超过w,限速点所在距离起点d距离处,然后道路的总长度为l。问你最少多少时间能够走完整条道路。

思路:

这题好麻烦啊。。。一不小心就会出错。

我是先求出到达w所需要的时间,然后利用v=a*t1算出到达w点时的速度,如果v<=w,那么说明是不会在那个点超速的,所以一直加速到车子速度的最大值就好了,然后判断一下长度是否走完了整条路,如果没有走完,则后面的运动都是匀速运动。

否则的话,

1)我们在0~d的距离内,首先进行加速,加速到最大值的时候然后再减速到w,然后越过w点后然后再继续加速,这里要注意一个问题,在d之前的时候并不是一直都是在减速的,我们可以首先先算出加速所需要的时间以及减速所需要的时间,然后中间可能有一段空的时间是保持以最大速度进行匀速直线运动的,这里我一开始没想到,所以一直wa。。

2)如果上面那种不行,那么我们只能用解方程的办法来求出车子在0~d的范围内所能到达的最大速度了。

首先我们设车子在0~d中间所能到达的最大速度为v,

v^2-0^2=2ax1 ..............(1)

v^2-w^2=2ax2..............(2)

然后两个方程相加就可以得到我们所要求的v了。

然后像前面那样进行利用公式进行一下判断就好了。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<cmath>
using namespace std;
#define maxn 10010
int main(){
double a,v;
double l,d,w;
scanf("%lf%lf",&a,&v);
scanf("%lf%lf%lf",&l,&d,&w);
double t=sqrt((2.0*d)/a*1.0);
double V=a*1.0*t;
V=min(V,v);
if(V<=w){
double tt=(v-0)/a;
double tot=0;
double xt=(a*tt*tt)/2;
if(xt<=l){
tot=tt+(l-xt)/v;
}
else{
double vt=sqrt(2.0*a*l);
tot=(vt-0)/a;
}
printf("%.10lf\n",tot);
return 0;
}
double t1=(v-0)*1.0/a;
double t2=(v-w)*1.0/a;
double xx=v*t1/2.0+(v+w)*t2/2.0;
double tsum=0;
if(xx<=d){
tsum=t1+t2;
double dis=d-xx;
tsum+=dis*1.0/v; //这里应该除的是v,因为我们可以让中间有一段一直保持匀速直线运动
double t3=(v-w)/a;
double x3=(v*v-w*w)/(2.0*a);
if(x3<=(l-d)){
tsum+=t3;
double x4=l-d-x3;
tsum+=(x4/v);
}
else{
double v3=sqrt(w*w+2.0*a*(l-d));
double t4=(v3-w)/a;
tsum+=t4;
}
}
else if(xx>d){
double v1=sqrt((w*w/2.0)+a*d);
double t3=(v1-0)*1.0/a+(v1-w)*1.0/a;
tsum=t3;
double t4=(v-w)*1.0/a;
double x4=(w+v)*t4/2.0;
if(x4<=(l-d)){
tsum+=t4;
tsum+=(l-d-x4)/v;
}
else if(x4>(l-d)){
double v2=sqrt(w*w+2*a*(l-d));
double t5=(v2-w)/a;
tsum+=t5;
}
}
printf("%.10lf\n",tsum);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息