【2023.03.17】T4 题解
1.题意:
M小学组织小朋友们去春游,一共有n个小朋友参加这次集体活动,他们需要走s米的路程才能到达目的地。每个学生的行走速度是v1,为了减少在路程上消耗的时间,学校决定租一辆公交车,公交车的座位可以容纳k个人,为了保证安全,公交车不能容纳k人以上,公交车的行驶速度是v2。为避免小朋友们出现晕车的情况,每个学生只能坐不超过1次的公交车。
公交车的停靠、倒车时间以及小朋友的上下车时间都可以忽略不计。现在请帮帮老师们确定n个学生到达目的地所需的最短时间。
2.输入输出格式
输入
只有一行:包括五个正整数n,s,v1,v2和k,分别代表学生数量、路程长度、学生行走速度、汽车驾驶速度和汽车可容纳人数。
(1<=n<=10000,1<=s<=1e9,1<=v1<v2<=1e9,1<=k<=n)
输出:
输出所有学生可以到达目的地的最短时间,误差不能超过0.000001
3.样例 :
样例输入 #1
5 10 1 2 5
样例输出 #1
5.0000000000
样例输入 #2
1 1 1 2 1
样例输出 #2
0.5000000000
样例输入 #3
10 20 1 2 5
样例输出 #3
14.0000000000
4. 样例解释
样例一:
5个学生可以全部上公交车,并且时间是10/2=5
样例二:
1个学生可以全部上公交车,并且时间是1/2=0.5
样例三:
10个学生,公交车一次可容纳5人,所以公交车需要接两次学生。第一次公交车带5个学生走到12米,共12/2=6分钟,5个学生下车后走到目的地需要(20-12)/1=8分钟,第一批学生到达终点需要14分钟。在12米处停车之后,公交车回去接剩下的学生,公交车和第二批学生在8米处相遇,
此时第二批学生走了8/1=8分钟,公交车带着第二批学生直接到达目的地,第二批学生坐车时间为(20-8)/2=6分钟,第二批学生共耗时8+6=14分钟。第一批学生和第二批学生用时相同,皆为14分钟。
5.数据范围
对于50%的数据,1<=s<=1000,1<=v1<v2<=1000
对于75%的数据,1<=s<=10000,1<=v1<v2<=10000
对于100%的数据,1<=s<=1e9,1<=v1<v2<=1e9
6.题外话:如果课上没听懂,可以看一下
一道非常简单的数学题(小学奥数课外班做过类似的……
首先做一道小(du)学(liu)数学题:
敲黑板
题意:
100个小学生去学校,在同一起点按直线出发,学校在1000米处,一人能坐一次车,每人都是1m/s的速度,而车与同学们一起出发,能载50人,5m/s,车能来回开(公交车的停靠、倒车时间以及小朋友的上下车时间都忽略不计)
请你帮小明老师设计小学生到达学校所需的最短时间(PS:司机不算人,老师也不算人
n:学生数量
S:总路程
V1:步行速度
k:公交车最大可载人数
V2:公交车速度
S1:临时步行路程
S2:临时公交车路程
ans:最短时间
先思考一下,最好画图
7.思路:
不难发现:
- 当所有学生步行的时间都相等时,所用时间最短
-
因为当有一个学生没有到终点,时间就没有停止流逝
-
所以时间的长短不在于第一个时间多短而在于最后一个时间多长
- 当第一个时间越短,最后一个时间就越长
-
所以我们要让它平衡,让每个人同时到达终点(但不是全走过去,不然车就废了)
-
既然所用时间相等,速度相等,那走出的路程也相等(
物理没白学
以上就是做该题的主要思路
思路有了(但你还是不会,再来看看如何解出这道小(du)学(liu)的题
8.解题:
如图
但这时候我们不知道S1是多少
由车一直送到最后一批人到终点的所有走过的路程所用时间(除了把第一批人送到需达到的地点的时间)与S1/V1相等这个条件可列一元一次方程 :
S1/V1==(2*S-3*S1)/V2
解得:
S1=(2*S*V1)/(3*V2+V2)
然后求时间:
由:
v=s/t
得:
t=s/v
人的路程有了S1,车的路程S2便是:
S2=S-S1
时间就是:
t=(S1/V1)+(S2/V2)
数自己代入,绝对没问题
那有如果150个小学生咋整……
这时候我们还是不知道S1是多少
由车一直送到最后一批人到终点的所有走过的路程所用时间(除了把第一批人送到需达到的地点的时间)与 S1/V1 相等这个条件可列一元一次方程 :
S1/V1==(4*S-5*S1)/V2
解得:
S1=(4*S*V1)/(5*V2+V2)
Q:有没有发现规律 ?
A:没有……
没错!!!
\(\color{red}{\text{让总人数除以车载人数再向上取整再减1再乘2!!!}}\)
就是这个式子:
sa=(ceil(n/k)-1)*2;
S1就等于
sa*v1*s/(v2+(sa+1)*v1)
就是这个式子:
s1=sa*v1*s/(v2+(sa+1)*v1);
时间还是那么算:
ans=s1/v1+(s-s1)/v2;
9.代码
#include <bits/stdc++.h>
using namespace std;
double n,k;
double v1,v2;
double s,t;
double ans=0;
inline long long read(){
long long s=0;
long long w=1;
char ch;
ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-'){
w=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=(s<<1)+(s<<3)+(ch^48);
ch=getchar();
}
return s*w;
}
inline void write(long long s){
if(s<0){
putchar('-');
s=-s;
}
if(s>9){
write(s/10);
}
putchar(s%10+'0');
}
int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
double s1,sa;
n=read();
s=read();
v1=read();
v2=read();
k=read();
sa=(ceil(n/k)-1)*2;
s1=sa*v1*s/(v2+(sa+1)*v1);
ans=s1/v1+(s-s1)/v2;
printf("%.10lf",ans);
//fclose(stdin);
//fclose(stdout);
return 0;
}
本文来自博客园,作者:Hzzxx,转载请注明原文链接:https://www.cnblogs.com/xinao2186182144/p/17227487.html