【poj2431】-Expedition

实现思路

这道题类似于【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;
}

猜你喜欢

转载自blog.csdn.net/weixin_44944046/article/details/113786379