25. 赶飞机

来源:互联网 发布:淘宝男士家居服 编辑:程序博客网 时间:2024/04/27 09:40

郭老师接到临时的出差任务,于是他匆忙的打车赶赴机场,眼看就要赶不上飞机了,幸好机场大厅里面有一些自动人行传送带,他决定利用它来减少到达候机楼的时间,但是他还是很着急,所以决定跑一段来加快达到的时间,现在假设:

1. 每个人行传送带都有一定的速度 v,人行传送带之间没有重叠。

2. 郭老师行走的速度是 w,那么在传送带上走的速度是 w + v

3. 郭老师跑步的速度是 r,那么在传送带上跑的速度就是 r + v

4. 郭老师决定跑 t 秒,对于时间 t 内,他不一定要连续跑,可以走走再跑,也不一定跑够时间 t

现在请你帮忙计算郭老师至少要需要多少时间才能达到候机楼。

输入

第一行为测试用例个数 T (1 ≤ T ≤ 40),每一组测试用例包含 5 个正整数,用空格分隔

  • x:距离候机楼的距离,郭老师起始位于0,1 ≤ X ≤ 1000000
  • w:郭老师走路的速度,1 ≤ w ≤ 100
  • r:郭老师跑步的速度,1 ≤ w < r ≤ 100
  • t:最多能跑的时间秒数,1 ≤ t ≤ 1000000
  • n:自动人行传送带的个数,1 ≤ n ≤ 500000

接下来的 n 行,表示 n 个自动人行传送带的详细信息。每行包含三个非负整数:bi,ei,vi,分别表示传送带的起始位置、终止位置和速度,0 ≤ bi < ei ≤ x,1 ≤ vi ≤ 100。任意两个传送带都不相交。

输出

包含一个数字,表示至少需要多少时间。输出四舍五入到6位小数。

测试输入关于“测试输入”的帮助期待的输出关于“期待的输出”的帮助时间限制关于“时间限制”的帮助内存限制关于“内存限制”的帮助额外进程关于“{$a} 个额外进程”的帮助测试用例 1以文本方式显示

  1. 3↵
  2. 10 1 4 2 2↵
  3. 0 1 1↵
  4. 9 10 1↵
  5. 10 1 4 1000 2↵
  6. 0 1 1↵
  7. 9 10 6↵
  8. 20 1 3 20 5↵
  9. 0 4 5↵
  10. 4 8 4↵
  11. 8 12 3↵
  12. 12 16 2↵
  13. 16 20 1↵
以文本方式显示
  1. 3.000000↵
  2. 2.300000↵
  3. 3.538095↵
1秒1024KB0


//让郭老师的平均速度尽可能快,那么首先应该使郭老师在越慢的传送带上//速度尽可能地快,注意地面可以看做速度为0的传送带,所以我们只需要对传送带进行排序//从速度最慢的开始跑,跑到没有时间后,郭老师再走即可#include<stdio.h>#include<stdlib.h>double X_GLS, W_GLS, R_GLS, T_GLS, N_SENT, X_SENT;typedef struct Sent//传送带结构{double L_sent;//单个传送带长度double V_sent;//单个传送带速度}sent;sent num[500005];int cmp(const void *a, const void *b)//排序规则为以速度的从小到大排序{return (*(sent*)a).V_sent > (*(sent*)b).V_sent ? 1 : -1;}int main(){int count;int Bi, Ei, Vi;scanf("%d", &count);while (count--){X_SENT = 0;//每次都要对传送带总长置零double Sum_Time = 0,T_gls,Ti;scanf("%lf %lf %lf %lf %lf", &X_GLS, &W_GLS, &R_GLS, &T_GLS, &N_SENT);T_gls = T_GLS;for (int i = 1; i <= N_SENT; i++){scanf("%d %d %d", &Bi, &Ei, &Vi);num[i].L_sent = Ei - Bi;num[i].V_sent = Vi;X_SENT += num[i].L_sent;//求传送带总长}num[0].L_sent = X_GLS - X_SENT;//第一个传送带即“地面传送带”num[0].V_sent = 0;qsort(num, N_SENT + 1, sizeof(num[0]), cmp);for (int i = 0; i <= N_SENT; i++){if (T_gls*(num[i].V_sent + R_GLS) >= num[i].L_sent)//在当前剩余的可跑步时间内能跑完当前传送带的长度{Ti = num[i].L_sent / (num[i].V_sent + R_GLS);T_gls -= Ti;Sum_Time += Ti;}else if (T_gls > 0)//在当前剩余的可跑步时间内不能跑完当前传送带的长度但是时间还是有剩余{Sum_Time += T_gls;//直接将时间加进来,然后从传送带长度上减去跑步长度即可double L_R = T_gls*(num[i].V_sent + R_GLS);//要准备减去的跑步长度T_gls = 0;Ti = (num[i].L_sent - L_R) / (num[i].V_sent + W_GLS);Sum_Time += Ti;}elseSum_Time += num[i].L_sent / (num[i].V_sent + W_GLS);//郭老师走路时间}printf("%.6lf\n", Sum_Time);}return 0;}