洛谷 P1135 奇怪的电梯

题目描述

呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第ii层楼(1 \le i \le N)(1iN)上有一个数字K_i(0 \le K_i \le N)Ki(0KiN)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如:3, 3 ,1 ,2 ,53,3,1,2,5代表了K_i(K_1=3,K_2=3,…)Ki(K1=3,K2=3,),从11楼开始。在11楼,按“上”可以到44楼,按“下”是不起作用的,因为没有-22楼。那么,从AA楼到BB楼至少要按几次按钮呢?

输入格式

共二行。

第一行为33个用空格隔开的正整数,表示N,A,B(1≤N≤200, 1≤A,B≤N)N,A,B(1N200,1A,BN)。

第二行为NN个用空格隔开的非负整数,表示K_iKi

输出格式

一行,即最少按键次数,若无法到达,则输出-11。

输入输出样例

5 1 5
3 3 1 2 5
3

 

分析

搜索入门好题,深搜广搜两种策略,深搜需要进行最优化剪枝。

 

代码

深搜

#include<bits/stdc++.h>
using namespace std;

int n,a,b;
int k[1000];
int ans=1000000000;
int book[1000];


void dfs(int floor,int step)
{
    if(floor==b)
    {
        ans=min(ans,step);
        return;    
    }
    if(step<ans) //最优化剪枝 
    {
        int new_floor_up=floor+k[floor];
        int new_floor_down=floor-k[floor];
        if(new_floor_up<=n&&book[new_floor_up]==0)
        {
            book[new_floor_up]=1;
            dfs(new_floor_up,step+1);
            book[new_floor_up]=0;
        }
        if(new_floor_down>=1&&book[new_floor_down]==0)
        {
            book[new_floor_down]=1;
            dfs(new_floor_down,step+1);
            book[new_floor_down]=0;
        }
    }
}



int main()
{
    cin>>n>>a>>b;
    for(int i=1;i<=n;i++)
    {
        cin>>k[i];
    }
    dfs(a,0);
    if(ans==1000000000) cout<<"-1"<<endl;
    else cout<<ans<<endl;
    return 0;
}

 

广搜

#include<bits/stdc++.h>
using namespace std;

int n,a,b;

struct Point
{
    int floor;
    int step;
    Point(int _floor,int _step):
        floor(_floor),step(_step){}
};

int k[1000];
int book[1000];
int ans=-1;

queue <Point> node;

int main()
{
    cin>>n>>a>>b;
    for(int i=1;i<=n;i++)
    {
        cin>>k[i];
    }
    node.push(Point(a,0));
    book[a]=1;
    while(!node.empty())
    {
        Point now_node=node.front();
        node.pop();
        if(now_node.floor==b)
        {
            ans=now_node.step;
            break;
        }
        Point new_node_up=Point(now_node.floor+k[now_node.floor],now_node.step+1);
        Point new_node_down=Point(now_node.floor-k[now_node.floor],now_node.step+1);
        if(new_node_up.floor<=n&&book[new_node_up.floor]==0)
        {
            book[new_node_up.floor]=1;
            node.push(new_node_up);
        }
        if(new_node_down.floor>=1&&book[new_node_down.floor]==0)
        {
            book[new_node_down.floor]=1;
            node.push(new_node_down);
        }
    }
    cout<<ans<<endl;
    return 0;
}

 

posted @ 2021-11-16 09:33  前排吃瓜  阅读(68)  评论(0编辑  收藏  举报