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

该博客介绍了Codeforces Beta Round #5的一道题目,涉及车辆遵循交通规则的问题。车辆以加速度a行驶,最大速度限制为v,需在经过距离d处的限速点时速度不超过w,总路程为l。博主解析了解题思路,包括如何计算到达限速点所需时间,判断是否超速,并讨论了两种情况:一是若不超速则全程加速或匀速,二是可能需要在限速点前加速、减速并再次加速。解题关键在于利用物理公式解决速度和加速度问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:

现在告诉你有一条道路,然后车子的加速度为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);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值