实现思路
这道题类似于【LeetCode45】-跳跃游戏的思想,等到不得不的时候再进行某事。
与那道题不同的是,跳跃只能单次而加油可以累加多个,但加油的原则是挑多的先加。
判断是否能到达终点,将整个长距离划分也就是先看当前的油是否能支撑到最近的加油点。
具体的步骤如下:
- 将加油站顺序按照距离终点的长度排序,由大到小
- 每一步计算两个加油站之间的距离,判断油量是否能支撑
- 当油量足以支撑时不加油,将经过的这一加油站数据保存到栈中
- 当油量不足以支撑时从大到小加油,并用变量记录加油数,加油加到足以支撑时就不再加油
- 当把能加的油都加了也不能满足距离,返回-1
- 每走一步更新油量
注意的点
- 更新油量
- 记得将终点的点也放在存储加油站的数据结构中,统一化处理得到结果
其实也有点分而治之的思想,每次都考虑的是两个加油站之间的距离而不是一个整体的大距离
实现代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
bool cmp(const vector<int> &a,const vector<int> &b) {
return a[0] > b[0];
}
int get_re(int L,int P,vector<vector<int>> &fuel)
{
int time = 0;
sort(fuel.begin(), fuel.end(), cmp);
priority_queue<int> h_fuel;
for (int i = 0;i < fuel.size();i++) {
int dis = L - fuel[i][0];
while (!h_fuel.empty()&&dis>P)
{
P += h_fuel.top();
h_fuel.pop();
time++;
}
if (dis > P) {
return -1;
}
P = P - dis;
L = fuel[i][0];
h_fuel.push(fuel[i][1]);
}
return time;
}
int main() {
int n;
while (scanf("%d", &n) == 1 && n) {
vector<vector<int>> fuel;
for (int i = 0;i < n;i++) {
int d, p;
scanf("%d%d", &d, &p);
vector<int> t;
t.push_back(d);
t.push_back(p);
fuel.push_back(t);
}
vector<int> t;
t.push_back(0);
t.push_back(0);
fuel.push_back(t);
int l, p;
scanf("%d%d", &l, &p);
printf("%d\n", get_re(l, p, fuel));
}
return 0;
}