题意:一辆车有一个油量的限制,给出目的地,每单位油跑多少单位距离,给出路上的几个加油站的价格和位置,若这辆车能跑到目的地问最少用多少钱,不能则输出最大的行驶距离。
思路:先把加油站按照距离从小到大排序,每次到达一个加油站后我们可以算出现在最远能到哪,遍历一下能跑到的加油站,若这个加油站的单价比车当前所在的加油站便宜,那就直接跑到当前遍历到的加油站,若不能则取遍历到的加油站中单价最小的作为下一个目的地,加满油跑。可以把终点当作一个单价为0的加油站。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAX_N = 10000;
struct Sta {
double d, p;
bool operator < (const Sta& s) const {
return d < s.d;
}
}s[MAX_N];
double c, d, avg;
int n;
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
scanf("%lf %lf %lf %d", &c, &d, &avg, &n);
for (int i = 0; i < n; i++) {
scanf("%lf %lf", &s[i].p, &s[i].d);
}
s[n].d = d; s[n].p = 0;
sort(s, s + n);
if (s[0].d > 0) {
printf("The maximum travel distance = 0.00\n");
return 0;
}
int p = 0;
double gas = 0.0;
double ans = 0.0;
bool flag = true;
for (;;) {
double mx = s[p].d + c * avg;
int nxt = -1; double mp = 1000000;
for (int i = p+1; i <= n; i++) {
if (s[i].d <= mx) {
if (s[i].p < s[p].p) {
mp = s[i].p; nxt = i;
break;
}
if (s[i].p < mp) {
mp = s[i].p;
nxt = i;
}
}
}
if (nxt == -1) {
flag = false; break;
}
if (mp >= s[p].p) {
ans += (c - gas) * s[p].p;
gas = c;
}
double tmp = (s[nxt].d - s[p].d) / avg;
if (tmp > gas) {
tmp -= gas; gas = 0;
ans += tmp * s[p].p;
} else {
gas -= tmp;
}
p = nxt;
if (p == n) break;
}
if (flag) {
printf("%.2lf\n", ans);
} else {
printf("The maximum travel distance = %.2lf\n", s[p].d + c * avg);
}
return 0;
}