汽车加油站问题(Java)

题目

在这里插入图片描述
在这里插入图片描述
代码如下

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;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值