Poj—2431 Expedition 优先队列使用经典例题

就像《挑战程序设计竞赛》所说的——在到达加油站之前时,就获得一次在之后加油的权利。简单的说就是,当你经过第 i 个加油站时,先别加油,先压入优先队列,当你到达第 k 个加油站时,计算你车里的油够不够,若不够则从优先队列中选取一个在前面几站中最大的加油站,若还不够,加第二大的加油站.....
总的来说,先考虑能不能到下一站,能,则不加油;不能,就加前面几站中最大的。
这道题目:
1.给你加油站的距离是到终点的距离,而非是到卡车的距离。
2.给你的加油站的距离是随机的,而非排过序的,即在我看来必须有对加油站排序一次(当然可能是我太弱鸡的,还有其他方法^-^,有的话请告诉我,希望您不吝赐教)
3.优先队列的使用,默认是从大到小输出
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 10000 + 10;
int the_num;
struct Node {
    int pos, fule;
};
Node stop[maxn];
int the_dis, have_fuel;
void solve() {
    priority_queue<int> que;
    int count = 0, current_position = 0;
    for (int i = 0; i <= the_num; i++) {
        int need_dis =stop[i].pos - current_position;
        while (need_dis > have_fuel) {
            if (que.empty()) {
                puts("-1");return;
            }
            have_fuel += que.top();
            que.pop();
            count++;
        }
        have_fuel -= need_dis;
        current_position =stop[i].pos;
        que.push(stop[i].fule);
    }
    printf("%d\n", count);
}
bool cmp(const Node& a, const Node& b) {
    return a.pos < b.pos;
}
int main() {
    while (scanf("%d", &the_num) == 1) {
        for (int i = the_num - 1; i >= 0; i--) {
            scanf("%d%d", &stop[i].pos, &stop[i].fule);
        }
        scanf("%d%d", &the_dis, &have_fuel);
        //题意是距离终点的距离而非是离开车的距离,具体可看Poj—2431的Hint
        for (int i = 0; i < the_num; i++) {
            stop[i].pos=the_dis-stop[i].pos;
        }
        //把终点当做一个加油站
        stop[the_num].pos = the_dis;
        stop[the_num].fule= 0;
        //对所有的站点排序
        sort(stop, stop + the_num + 1, cmp);
        solve();
    }
    return 0;
}

如果先要快速掌握优先队列的STL的使用方法转:http://blog.csdn.net/notcoldheike/article/details/76915753
谢谢观看(^-^)!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值