这是一道贪心 + 模拟的题。
贪心思路比较好想,很考验模拟功底。难点在于需要维护的东西很多。
一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市,途中有N个加油站,有选择性地加油。若能到达目的地,输出最少费用;反之,输出“No Solution”。
样例输入
275.6 11.9 27.4 2.8 2
102.0 2.9
220.0 2.2
样例输出
26.95
我们可以定义一个结构体来储存,第i个加油站与起点的距离,和每升油的价钱(不定义也没事,也就用2或3个数组而已)
const int size = 505;
struct T {
int index;
double p, f;
} a[size];
首先,因为最开始油箱是空的(题目给出了的),所以在起点必须加油,然后我们需要思考的是加多少油,也就是思考这道题的贪心策略————怎么加油使得费用最少。
我们还要思考的是什么时候输出“No Solution”。举个例子:
input:10 2 1 5 2
5 10
6 7
分析一下数据:油箱最大容量是2升,每升最多行驶距离为1,所以我们可以算出一次加油后最多能行驶的距离为2。
而第一个加油站与起点的距离为5,即使在起点加满油也无法到达第一个加油站,所以旅行失败,输出”No Solution“。
之后也是同理,设加满油能行驶的最大距离为 M a x Max Max,只要 a [ i ] . f − a [ i − 1 ] . f > M a x a[i].f - a[i - 1].f > Max a[i].f−a[i−1].f>Max的都是无解的。
可以在输入时预处理,筛出失败的,如下
a[0].f = 0;
for (int i = 1; i <= N; i++) {
scanf("%lf %lf", &a[i].f, &a[i].p);
if (a[i].f - a[i - 1].f > C * D) {
//C * D为加满油行驶的最大距离
printf("No Solution");
return 0;
}
}
要想费用最少,不难想到在油价最便宜的加油站加油。但仅仅这样范围太大了,但我们由上一种情况可知,可选的加油站距离起点的距离肯定在a[i].f ~ a[i].f + C * D之间。
这里又需要分两种情况:1.在区间内有油价低于当前油价的加油站;2.没有油价低于当前油价的加油站。
若有,且剩余油量无法到达该加油站,则在当前加油站加油,加到恰好能到达该加油站的油量即可;否则,就直接去到该加油站。
若没有,则在当前加油站加满油,开到此区间中油价最便宜的加油站再做这样的考虑。最重要的一点是,在这种情况中还要判断,如果当前加油站与目的地距离小于等于C * D,就可
加油至刚好到目的地的油量。
题目中还提示了你可能还会有N为0的毒瘤存在,因此我试了试,我这个想法在N为0时可能没有输出,所以要特判一下。
在我的程序里,需要维护的东西有4个:1.费用(必须的啊);2.所处加油站的编号;3.已经行驶的距离;4.剩下的油量。
于是我便开始了我的的尝试:
#include <cstdio>
#include <climits>
#include <algorithm>
using namespace std;
const int size = 505;
struct T {
double p, f;