【代码超详解】POJ 2431 Expedition 远征(优先队列 + 贪心 + 思维)

博客详细讲解了如何使用优先队列和贪心策略解决一道编程题,即奶牛远征途中寻找最少加油次数到达小镇的问题。通过模拟卡车行驶过程,对加油站信息进行排序和处理,最终实现最少加油次数的计算。若无法到达小镇,则输出-1。
摘要由CSDN通过智能技术生成

一、题目描述

一群奶牛劫了一辆卡车并深入丛林去远征探险。但由于司机的驾驶技术太辣鸡,这些奶牛很不幸地碾过一颗石头,划破了卡车的油箱。现在,这辆卡车每行驶 1 公里就要漏 1 个单位的油。
为了修车,奶牛需要经过一条长长的刮大风的路把车开到最近的一个镇上(距离不超过 1 000 000 个单位)。路上,在乡镇和当前位置之间有 N(1 ≤ N ≤ 10 000)个加油站,奶牛可以停下并获得 1 到 100 单位的额外燃油。
丛林对人类来说是一个危险之地,对奶牛来说更是。因此,奶牛希望在去往镇上的路上能够使加油次数最少。幸运的是,卡车的油箱很大,可以认为容量无限。这个卡车当前距离小镇有 L 单位远,且当前剩余 P 单位的燃油(1 ≤ P ≤ 1 000 000)。
计算到达小镇需要停车加油的最少次数,或者判定奶牛根本无法到达小镇。
输入第一行一个整数 N ,第 2 到 N + 1 行每行两个整数,空格分隔,描述每个加油站到乡镇的距离和油站能提供的燃油量。第 N + 2 行是两个整数 L 和 P ,空格隔开。
输出一行一个整数:最少需要的加油次数。如果无法到达镇上,输出

-1

样例
输入:

4
4 4
5 2
11 5
15 10
25 10

输出:

2

二、算法分析说明与代码编写指导

从解决问题的角度,卡车从某位置一直开到没油再隔空从已经过的加油站中选取若干个站抽取燃油,与到这若干个站先加油再继续走,最终没油停下的位置是一样的。
设 pos 为当前位置,初值 0 ,idx 用于遍历从起点或上一次燃油耗尽停车到本次燃油耗尽停车走过的路上经过的加油站。优先队列 q ,存储加油站信息的有序对数组 p ,d 为停车位置到下一个加油站的距离。
为了方便,先把读入的加油站到终点的距离改成到起点的距离,然后按起点距离从小到大排序。假想一个正好在终点的“加油站”,否则下面的循环会给出错误的结果。
然后就是模拟开车停车的过程。先用完汽油走到停下为止,然后统计这段路经过的加油站数量,将这些油站的加油量存到优先队列中。注意优先队列的比较函数是 less ,这样压入队列顶端的数总是比底端的数大,也就是说队列从顶端(头部)往底端递减,如果写成 greater 就会 Wrong Answer 。然后计算停下的位置到下一个加油站的距离,然后从队列中取出若干个能加油最多的加油站的油加到卡车上,并递增加油次数,接着继续重复刚才的过程。如果最终能走到 L 的距离,就意味着可以到达小镇,输出相应的加油次数。如果某次停下后即使抽完从上一次停车点到当前位置的路上经过的全部加油站都无法到达下一个加油站,自然就无法到达小镇,输出 -1 。
当遍历完最后一个加油站时,d 会变成到终点的距离,继续走完最后一次循环。

三、AC 代码

(16 ms)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值