SCAU 数据结构 18718 航行(BFS) C++

18718 航行

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

题型: 编程题 语言: G++;GCC
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的情况。

解题思路

定义一个结构体,我自己命名为Feichuan,里面存放飞船现在的属性,包括现在的位置、能量和银河币,再创建一个空队列用来存放前进过程中飞船的属性,这里队列可以直接用C++自带的queue函数,也可以用数据结构书上的原理代码,也可以用结构体数组模拟队列。本代码用的是queue函数,因为比较方便(其实自己想偷懒 )。
队列构建完毕后,先将出发点位置的飞船压入队列,此时飞船的属性:位置为0,能量为power,银河币为money。然后构建一个循环,当队列不为空时,将队首元素赋值给tem后将队首元素pop出去,此时tem代表的是飞船行进到tem.loc位置时的状态,tem.power表示其现在的能量,tem.money表示其现在的银河币。然后进行判断,如果现在飞船能直接抵达终点(条件为tem.power+tem.loc>=终点位置),输出yes并return 0就好,如果不能直接到达终点,那么我们就要把该位置飞船能到达前方不同空间站的情况存入队列中,记得存入的是到达某空间站更新后的飞船属性。

代码实现

#include <cstdio>
#include <queue>//C++队列头函数
using namespace std;
typedef struct
{
    int loc;
    int spend;
}Weizhi;//空间站的位置和补充飞船能量的花费
typedef struct
{
    int loc;//位置
    int power;//能量
    int money;//银河币
}Feichuan;//某时刻飞船的状态
int main()
{
    queue <Feichuan> b;//创建一个结构为Feichuan的队列
    int n,des,power,money;//空间站数量,终点位置,初始能量,初始银河币
    Feichuan tem;
    scanf("%d%d%d%d",&n,&des,&power,&money);
    Weizhi a[n];//存放不同空间站的属性
    int i;
    for(i=0;i<n;i++)
        scanf("%d%d",&a[i].loc,&a[i].spend);
    tem={0,power,money};//将出发点飞船的属性赋值给tem
    b.push(tem);//压入队列
    while(!b.empty())//如果队列不为空
    {
        tem=b.front();//将队首元素赋值给tem
        b.pop();//队首元素出队
        if(tem.power+tem.loc>=des)//如果此时的飞船能直接到达终点
        {
            printf("Yes");
            return 0;
        }
        for(i=0;i<n;i++)//循环寻找此时飞船能抵达的前方空间站
        {
            if(a[i].loc>tem.loc&&tem.loc+tem.power>=a[i].loc)//能抵达
            {
                Feichuan tem2;
                if(a[i].spend<=tem.money)此时飞船的银河币能够支付补满能量的花费
                     tem2={a[i].loc,power,tem.money-a[i].spend};//位置和money更新,能量为满
                else tem2={a[i].loc,tem.power-(a[i].loc-tem.loc),tem.money};//如果不够支付,位置和能量更新,money不变
                b.push(tem2);//进队
            }
            if(a[i].loc>tem.loc&&tem.loc+tem.power<a[i].loc)//如果此时的飞船已经无法抵达前方再前的空间站,直接跳出小循环即可
                break;
        }
    }
    printf("No");
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值