您的位置:首页 > 其它

hiho一下 第六十五周

2015-10-10 15:21 225 查看
题意分析

给定一条单行道的高速公路,汽车都是从坐标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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: