hiho一下 第六十五周
2015-10-10 15:21
225 查看
题意分析
给定一条单行道的高速公路,汽车都是从坐标0,向坐标无穷移动。又因为是单行道,所以后面的车无法超越前面的车。在时刻0时,有 N 辆车同时进入这条单行道,第i辆车从坐标x[i]进入,并且将会从坐标y[i]处驶出(保证y[i]>x[i])。在行驶过程中,汽车总会保持尽可能快的速度行驶,且第i辆车的最大速度为v[i]。问每辆车离开高速公路的所花费的时间。
算法分析
刚拿到本题,相信最开始的想法都会是计算追及问题。然而若从这个角度去考虑的话,这题会变得非常复杂。因此我们必须要使用题目的一些特殊的性质。
根据题目的描述,该条高速公路为单行道,无法超车,我们可以有:
那么这个性质有什么用呢?
首先第一点:
也就是说,最前面的一辆车一定不受任何车影响,所以x[i]最大的车一定是按自己最大速度行驶到y[i]。
然后我们在考虑第二辆车时,因为第一辆车的情况我们已经清楚,所以第二辆车也就比较容易计算。
依次类推,我们若按照汽车从前往后的顺序进行处理,考虑的因素会比较少一点。
所以我们读入数据之后要做的第一件事是根据x[i]进行排序。再根据x[i]从大到小进行处理。
就算是优化了处理顺序,追及问题仍然很麻烦。对于第i辆车,我们要考虑在它离开单行道,会追上多少辆车,光是想想就觉得头疼。
所以我们必须要考虑其他的途径,这里我们需要用到不能超车这个条件产生的第二的性质:
我们举个例子来说明:
|—c—c—|—>
j i k
其结果会有3种:
三种情况下,车j经过点k的时间都是大于等于车i的。
同理我们可以将这个情况扩展:
得到的这个性质又有什么用呢?我们仍然用一个例子来说明:
—–c—–c—–|—–|—–>
j i y[i] y[j]
我们首先根据这个性质,先计算出i,j分别到达y[i]的时间t[i],t[j]。
若t[j]
给定一条单行道的高速公路,汽车都是从坐标0,向坐标无穷移动。又因为是单行道,所以后面的车无法超越前面的车。在时刻0时,有 N 辆车同时进入这条单行道,第i辆车从坐标x[i]进入,并且将会从坐标y[i]处驶出(保证y[i]>x[i])。在行驶过程中,汽车总会保持尽可能快的速度行驶,且第i辆车的最大速度为v[i]。问每辆车离开高速公路的所花费的时间。
算法分析
刚拿到本题,相信最开始的想法都会是计算追及问题。然而若从这个角度去考虑的话,这题会变得非常复杂。因此我们必须要使用题目的一些特殊的性质。
根据题目的描述,该条高速公路为单行道,无法超车,我们可以有:
对于任意两辆车i,j,若x[i]<x[j],则车i始终在车j之后。
那么这个性质有什么用呢?
首先第一点:
在前面的汽车始终不受后面的汽车影响。
也就是说,最前面的一辆车一定不受任何车影响,所以x[i]最大的车一定是按自己最大速度行驶到y[i]。
然后我们在考虑第二辆车时,因为第一辆车的情况我们已经清楚,所以第二辆车也就比较容易计算。
依次类推,我们若按照汽车从前往后的顺序进行处理,考虑的因素会比较少一点。
所以我们读入数据之后要做的第一件事是根据x[i]进行排序。再根据x[i]从大到小进行处理。
就算是优化了处理顺序,追及问题仍然很麻烦。对于第i辆车,我们要考虑在它离开单行道,会追上多少辆车,光是想想就觉得头疼。
所以我们必须要考虑其他的途径,这里我们需要用到不能超车这个条件产生的第二的性质:
对于道路上任意一点k,两辆车i,j,若车i在车j前,则车j经过该点的时间一定大于等于车i经过该点的时间。
我们举个例子来说明:
|—c—c—|—>
j i k
其结果会有3种:
车i到达k点时,车j仍未追上i |---c---|c------> j ki 显然车j还要再经过一段时间才能到达k,那么i经过k的时间一定小于j。 车i到达k点时,车j刚好追上i |------|cc------> kji 显然车j和车i同时到达k,那么i经过k的时间等于j 车i到达k点前,车j就已经追上i |---cc------|---> ji k 这种情况下,车j的最大速度显然大于车i。但是车j不能超过车i,当车j追上车i时,就以和车i同样的速度前进。那么他们通过k点时间一定是相同的。
三种情况下,车j经过点k的时间都是大于等于车i的。
同理我们可以将这个情况扩展:
对于多个车来说,最后一个车经过某个点的时间一定大于或等于前面的车经过该点时间的最大值。
得到的这个性质又有什么用呢?我们仍然用一个例子来说明:
—–c—–c—–|—–|—–>
j i y[i] y[j]
我们首先根据这个性质,先计算出i,j分别到达y[i]的时间t[i],t[j]。
若t[j]
#include <cstdio> #include <algorithm> using namespace std; struct Car { int X; int Y; int L; double T; int ID; } A[1010], B[1010]; bool cmp1(Car a, Car b) { return a.X > b.X; } bool cmp2(Car a, Car b) { return a.Y < b.Y; } bool cmp3(Car a, Car b) { return a.ID < b.ID; } int main() { int N; scanf("%d", &N); for (int i = 0; i < N; i++) { scanf("%d%d%d", &A[i].X, &A[i].Y, &A[i].L); A[i].ID = i; B[i].Y = A[i].Y; } sort(A, A + N, cmp1); sort(B, B + N, cmp2); for (int i = 0; i < N; i++) { bool flag = true; for (int j = 0; j < N; j++) { if (B[j].Y >= A[i].X && B[j].Y <= A[i].Y) { if (flag) { B[j].T = max(B[j].T, 1.0 * (B[j].Y - A[i].X) / A[i].L); flag = false; } else { B[j].T = max(B[j].T, B[j-1].T + 1.0 * (B[j].Y - B[j-1].Y) / A[i].L); } if (B[j].Y == A[i].Y) A[i].T = B[j].T; } } } sort(A, A + N, cmp3); for (int i = 0; i < N; i++) printf("%.2lf\n", A[i].T); return 0; }
相关文章推荐
- 任务调度利器-Celery
- iOS----友盟分享完善版本
- 二叉树前序遍历、中序遍历、后序遍历及算法
- getevent/sendevent 使用说明
- 软工视频之软件生命周期
- java 小记
- hdu 5489(最长上升子序列)
- unity的一些特殊目录
- POJ 3279 Fliptile(暴力)
- Linux 下查看局域网内所有主机IP和MAC
- ORA-12519: TNS:no appropriate service handler found 解决
- iPhone-获取网络数据或者路径的文件名以及后缀
- 我的进阶曲线之五
- Sublime Text3 快捷键汇总
- read PSE TPS2384 POE Firmware Guide
- mysql修改字符集utf8
- 问题总结
- Java计算某月第几个星期几的日期
- Hadoop系统架构
- 转:QT如何将.UI文件转成.h或.cpp文件