题目
代码如下
package day07;
import java.util.Comparator;
import java.util.PriorityQueue;
public class 卡车开车问题 {
public static void main(String[] args) {
int N = 4; int L = 25; int P = 10;
int[] A = {10,14,20,21};
int[] B = {10,5,2,4};
int min = getMin(N,L,P,A,B);
System.out.println(min);
}
//参数说明
//N:有N个加油站
//L:需要行驶的距离,也就是终点的距离
//P:卡车本身上有P单位的汽油
//A:第i个加油站再距离起点Ai单位距离的地方
//B: 每个加油站最多给汽车加Bi单位的油
public static int getMin(int N,int L,int P,int[] A,int[] B){
//为了方便操作将终点也看成一个加油站
A[N-1] = L;
B[N-1] = 0;
//汽车需要加油的次数
int res = 0;
//当前汽车距离起点的距离
int pos = 0;
//汽车中的油量
int tank = P;
//Java中的优先队列默认是按从小到大的排列的
//取数据也是从最小的那个开始取,这不符合我们题目
//comparator 是将我们优先队列从大到小进行排列,取值从最大的开始取
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
};
//维护加油站的优先队列
PriorityQueue<Integer> que = new PriorityQueue<>(comparator);
//我们可以改变一下思考方式。
//在到达加油站时,就获得了一次在之后的任何时候都可以加Bi单位汽油的权利
//在解决问题上也是一样的,当我们汽车没油的时候,需要油的时候,
//就认为是在之前经过的加油站加的油就可以了
for (int i = 0; i < A.length; i++) {
//接下来要前进的距离,也就是要达到下一个加油站的距离
int d = A[i] - pos;
//当汽车中的油量 不足以支撑到下一个加油站的时候,就加一次油
//当要判断汽车是否能正常行驶到下一个加油站
//刚开始que是没有数据的,也就是汽车没有行驶到下一个加油站。
//所有当汽车行驶不到第一个加油站的时候,会返回-1
while (tank-d<0){
if(que.isEmpty()){
//如果加油站没油,就return;
return -1;
}
tank+=que.peek();
//减去该加油站的加油次数
que.remove();
//增加汽车加油的次数
res++;
}
//更新汽车当前的位置
pos = A[i];
//将当前加油的机会放入优先队列
que.add(B[i]);
//更新汽车的油量
tank-=d;
}
System.out.println(pos);
return res;
}
}