宽搜(BFS)经典&简单题目 - 奇怪的电梯

Description

有一个奇怪的电梯,它可以停在任何一层楼,并且在每一层楼上有一个数字Xi 。


这个电梯只有两个按钮:UP 和 DOWN。


当你在第 i 层楼的时候,如果你按 UP ,那么你将上升 Xi 层楼(即是说你将到达第 i+Xi 层楼),


如果你按 DOWN,那么你将下降 Xi 层楼(即是说你将到达第 i-Xi 层楼)。


当然,你最多到达第 N 层楼,至少到达第 1 层楼。


例如,有一个5层楼的建筑,并且X1=3,X2=3, X3=1, X4=2, X5=5。


假如最开始你在第 1 层楼,那么此时如果你按 UP 的话,你将到达第4层楼(X1=3,1+3==4),


但是此时如果你按 DOWN 的话,则电梯不能操作,因为你不能到达 -2 层楼(X1=3,1-3 == -2)。


现在的任务是:假如你在第 A 层楼,你想去第 B 层楼,那么你至少需要按几次按钮(UP 或 DOWN)??

Input

多组输入


第一行输入三个数N,A,B (2 <= N,A,B <= 1000)


当 N==0时,输入结束。


第二行输入 N 个非负整数(即是题目描述中的Xi)。


Output

若能从A 到达B,则输出最少的按键数,否则输出 -1


Sample Input

5 1 5


3 3 1 2 5


2 1 2


55   6666


0

Sample Output

3


-1

这道题目是BFS【宽度优先搜索】里面很经典的题目,运用到了使用队列来进行宽搜的技巧。


#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

int lift[1005];
bool vis[1005];
int A, B, N;
struct node
{
    int step, floor;
};

int BFS()
{
    node cur, tmp_up, tmp_down;
    cur.step = 0;
    cur.floor = A;
    queue<node> Q;
    Q.push(cur);
    vis[A] = true;

    while (!Q.empty())
    {
        cur = Q.front();
        Q.pop();
        if (cur.floor == B)
            return cur.step;

        tmp_up.floor = cur.floor + lift[cur.floor];
        if (vis[tmp_up.floor] == false && tmp_up.floor <= N && tmp_up.floor >= 1)
        {
            tmp_up.step = cur.step + 1;
            Q.push(tmp_up);
            vis[tmp_up.floor] = true;
        }
        tmp_down.floor = cur.floor - lift[cur.floor];
        if (vis[tmp_down.floor] == false && tmp_down.floor >= 1 && tmp_down.floor <= N)
        {
            tmp_down.step = cur.step + 1;
            Q.push(tmp_down);
            vis[tmp_down.floor] = true;
        }
    }
    return -1;
}

int main()
{

    while (scanf("%d", &N) != EOF)
    {
        if (N == 0) break;
        scanf("%d%d", &A, &B);

        for (int i = 1; i <= N; ++i)
            scanf("%d", &lift[i]);
        memset(vis, false, sizeof(vis));

        printf("%d\n", BFS());
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值