18718 航行

18718 航行

时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0

题型: 编程题 语言: 不限定

Description

银河帝国正走向覆亡。为保留文明的种子,你需要驾驶飞船将一批“颛家”从帝国首都护送至银河边缘的基地。
现在已知航线是一条直线,帝国首都为起点(坐标0),基地为终点(坐标L),在这条航线上有N个空间站可以补充飞船的能源。
第i个空间站的坐标为ai,飞船停靠在第i个空间站必须花费bi个银河币,同时让你的飞船能量恢复为最大值M。
出发前飞船的能量是满额的M,每一点能量都可以让飞船航行一个坐标单位。

现在你已经通过募捐(榨篇)获得了S个银河币,请计算下飞船能否到达基地。

输入格式

第一行输入四个个数字N,L,M,S;(1<=N<=200) (1<=L<=20000) (1<=M<=20000) (0<=S<=20000)
接下来N行,每行输入两个数字,ai,bi (0<=ai<=L) (0<=bi<=20000)

输出格式

仅一行,如果能到达基地,输出Yes,否则输出No

输入样例

1 10000 5000 20000
5000 20000

输出样例

Yes

提示

样例说明,飞船可以花费5000能量到达一号空间站,花光20000银河币补满能量后,再行驶5000到达基地。
程序设计和数据结构设计都要考虑边缘数据。例如本题目,可能存在无需补给就直接行驶到基地的情况,也能存在bi>s的情况。

#include<iostream>
#include<cstdio>
using namespace std;
#include<queue>
int main(void) {
    int N, L, M, S;
    //N个空间站
    //L:基地终点
    //M:初始能量值
    //S:银河币
    cin >> N >> L >> M >> S;
    //能量站位置
    int position[205];
    //能量站恢复能量需要的银河币
    int cost[205];
    //当前能量
    int power = M;
    //当前位置
    int cur = 0;
    //输入能量站位置
    for (int i = 1; i <= N; i++) {
        cin >> position[i];
        cin >> cost[i];
    }
    //这里一定要先设置 起点0的位置
    position[0]=0;
    cost[0] = 0;
    //定义当前 三个队列
    queue<int>pos, money, pow;
    //一定要让起点位置进队
    pos.push(0);
    money.push(S);
    pow.push(M);
    //定义一个flag
    int flag = 0;
    int curpos, curmoney, curpow;

    while (1) {
        //如果队空  退出
        if (pos.empty()) {
            break;
        }
        //判定
        curmoney = money.front();
        curpos = pos.front();
        curpow = pow.front();

        //如果能量大于等于 终点-能量站 说明能到达  退出
        if (L - position[curpos] <= curpow) {
            flag = 1; break;
        }

        //当站数N>到达的k站数的时候
        if (curpos < N) {
            //    如果能够购买                能量M大于离下一个能量站的距离
            if (curmoney >= cost[curpos] && M >= position[curpos + 1] - position[curpos]) {
                //入队减少后的钱
                money.push(curmoney - cost[curpos]);
                //入队下一个能量站位置
                pos.push(curpos + 1);
                //能量回满到M然后减去到达下一个能量站需要的能量
                pow.push(M - (position[curpos + 1] - position[curpos]));
            }

            //    如果不购买 且现有能量能够到达下一个站
            if (curpow >= position[curpos + 1] - position[curpos]) {
                //入队未消耗的钱
                money.push(curmoney);
                //入队下一个站
                pos.push(curpos + 1);
                //下一次的能量为 当前能量-距离
                pow.push(curpow - (position[curpos + 1] - position[curpos]));
            }
        }

        //如果到了最后一个站  这里要特殊判断
        if (curpos == N) {
            //            如果能够购买 并且  能量M大于最后的距离
            if (curmoney >= cost[curpos] && M >= L - position[curpos]) {
                flag = 1;
                break;
            }
            //     当前能量走得到终点
            if (curpow >= L - position[curpos]) {
                flag = 1;
                break;
            }
        }

        money.pop();
        pos.pop();
        pow.pop();
    }
    if (flag == 1)cout << "Yes"; else cout << "No";
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值