题目描述
一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离D1、汽车油箱的容量C(以升为单位)、每升汽油能行驶的距离D2、出发点每升汽油价格PP和沿途油站数N(N可以为零),油站ii离出发点的距离Di、每升汽油价格Pi(i=1,2,…,N)。计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。
输入格式
第一行,D1,C,D2,P,N
接下来有N行。
第i+1行,两个数字,油站i离出发点的距离Di和每升汽油价格Pi。
输出格式
所需最小费用,计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。
解题思路
这一题,有点麻烦,本来想用滚动数组的,就像P1004那样,但是有个问题,里面涉及到汽车油量的问题,如果前面的油没用完,那么会影响到后面的花费问题,也就是说,它们并不是一个相互独立的问题,而是相互关联的。
但是我们可以结合实际去考虑这一题,现实生活中,我们如果进行长途旅行,如果两个加油站之间的距离,就算我们用完汽车油箱里所有油都到不了,那就只能输出"No Solution"了,表示我们无能为力啊,实在到不了。然后就算我们到得了,也要考虑花费问题,毕竟省下来的钱我们可以用来买好多好吃的。这里我们可以知道C*D2是我们的能到达范围。如果在能到达的范围内有一个加油站比现在所处的加油站油价便宜,那么只要刚刚好到那个加油站就好了,因为后续的路我们可以用更加便宜的油行驶下去,如果不巧,我们能到达的范围油价都比我们现在所处的加油站的油价贵,那么加满,并且选择那些贵的加油站中的最便宜的加油站作为下一次加油点。一次一次行驶下去,最后到了终点城市,这时候,油箱里应该没有剩下油了,才能说明我们花的钱用的刚刚好。
因为我是自学这些题的,所以不懂实际怎么判断正确性,但是注意,这道题里有个测试点的答案在0.01位置上是0,我第一次输出没有输出这个0,结果就WA了,还是太年轻了。
Talking is cheap,show you my code.
代码
#include<iostream>
#include <iomanip>
using namespace std;
double d1;
double c;
double d2;
double p;
int n;
double pi[8];
double di[8];
double cost;
int main() {
cin >> d1 >> c >> d2 >> p >> n;
double h = 0;//汽车油量
for (int i = 1;i <= n;i++) {
cin >> di[i] >> pi[i];
}
pi[0] = p;
di[n + 1] = d1;
for (int i = (n+1) ;i > 0;i--) {
di[i] -= di[i - 1];
if (di[i] > (c * d2)) {
cout << "No Solution" << endl;
return 0;
}
}
int flag = 0;//汽车到的位置
while (flag != (n + 1)) {
int i = flag + 1;
double len = 0;
double minp = 500;
int pmin = i;
while ((len+di[i]) <= (c*d2)) {
len += di[i];
if (pi[i] < minp) {
minp = pi[i];
pmin = i;
if (pi[i] <= pi[flag]) {
break;
}
}
i++;
}
if (minp <= pi[flag]) {
cost += ((len / d2) - h)*pi[flag];
h = 0;
}
else {
cost += (c - h)*pi[flag];
h = c - len / d2;
}
flag = pmin;
}
cout << setprecision(2) << fixed << cost << endl;
return 0;
}