POJ2431

生命不息,奋斗不止!

@author stormma
@date 2017/10/20

题意:一辆卡车距离城镇L单位长度,初始有P油,每行驶一个单位长度消耗一单位油。有n个加油站可以加油,给出n个加油站与城镇的距离Ai,和在加油站可以加的有的量Bi,问最少加油几次才能行驶L长度,如果不能输出-1。
我们稍微变换一下思路:每次经过加油站,都把油装到瓶子里面带走,Bi加入优先队列,到需要加油的时候才加,因为需要使加油的次数最少,每次都是选油量最大的加。如果优先队列为空而没有到达下一加油站或是终点。则不能够到达。

思路分析
换个思路想,我们判断从加油站A到B,如果不能到,我们加之前最大油量的加油站的油,那么问题来了,我们怎么维护前面加油站的油量呢?可以用优先队列,判断不能到B,就取出队加油,如果还不能到,继续加,这样保持加的都是最大加油站的油,直到队列为空,还不到就输出-1即可。

实现代码

package me.stormma.poj;

import java.util.*;

/**
 * 加油站问题 <a href="">题目链接</a>
 *
 * @author stormma
 * @date 2017/10/19
 */
public class Main2431 {

    private static int solve(List<Stop> stops, int L, int P) {
        PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2.compareTo(o1);
            }
        });
        // ans加油次数,pos当前距起点位置,tank当前
        int ans = 0, pos = 0, tank = P;
        for (Stop stop : stops) {
            // 到下一个加油站的距离
            int dis = stop.dis - pos;
            // 如果到不了,加油
            while (tank < dis) {
                if (queue.isEmpty()) {
                    return -1;
                }
                // 加经过的加油站最大加油量的
                tank += queue.poll();
                ans++;
            }
            tank -= dis;
            // 更新当前位置
            pos = stop.dis;
            // 向优先队列中增加这个加油站的油量
            queue.add(stop.tank);
        }
        return ans;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 加油站数量
        int N = in.nextInt();
        // 距离终点的距离
        List<Stop> stops = new ArrayList<>();
        for (int i = 0; i < N; i++) {
            stops.add(new Stop(in.nextInt(), in.nextInt()));
        }
        // 起点到终点的距离
        int L = in.nextInt();
        // 起始油量数
        int P = in.nextInt();
        for (Stop stop: stops) {
            stop.dis = L - stop.dis;
        }
        // 终点当做加油站
        stops.add(new Stop(L, 0));
        Collections.sort(stops, (o1, o2) -> o1.dis - o2.dis);
        System.out.println(solve(stops, L, P));
    }

    static class Stop {
        /**加油站距离起始位置的距离*/
        int dis;

        /**加油站一次可以加的油*/
        int tank;

        public Stop(int dis, int tank) {
            this.dis = dis;
            this.tank = tank;
        }
    }
}
发布了108 篇原创文章 · 获赞 250 · 访问量 9万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章