CCF NOI1078. 奇怪的电梯【递归】【广度优先搜索】

时间限制: 1000 ms  空间限制: 262144 KB  具体限制  

题目描述

大楼的每一层楼都可以停电梯,而且第i层楼(1<=i<=N)上有一个数字Ki(0<=Ki<=N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如:3 3 1 2 5代表了Ki(K1=3,K2=3,……),从一楼开始。在一楼,按“上”可以到4楼,按“下”是不起作用的,因为没有-2楼。那么,从A楼到B楼至少要按几次按钮呢?

输入

输入文件共有二行,第一行为三个用空格隔开的正整数,表示N,A,B(1≤N≤200, 1≤A,B≤N),第二行为N个用空格隔开的正整数,表示Ki。

输出

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

样例输入

5 1 5
3 3 1 2 5

样例输出

3

 

题记:

找最短步数,想到用广度优先搜索。

 

C++程序如下:

#include <iostream>
#include <queue>

using namespace std;
const int N = 2000;
int n, a, b;
int k[N];
bool flag[N], f;

typedef struct{
	int step;  //当前走了多少步
	int floor; //现在所处楼层 
} note;

queue <note> lift; //定义优先队列
note start, end; //定义起点层,终点层

void bfs(int a, int b){
	//初始化:走了零步,楼层为当前层,并入队 
	start.step = 0;
	start.floor = a;
	lift.push(start);
	//开始广度优先搜索 
	while(!lift.empty()){
		//更新当前楼层 
		start = lift.front(); 
		lift.pop(); 
		//走到指定楼层,输出步数,结束搜索 
		if(start.floor == b){
			cout << start.step << endl;
			f = 1;
			break;
		} 
		//电梯上升 
		if(start.floor + k[start.floor] <= n && !flag[start.floor + k[start.floor]]){
			end.floor = start.floor + k[start.floor];
			end.step = start.step +1;
			flag[end.floor] = 1;
			lift.push(end); 
		}
		//电梯下降 
		if(start.floor - k[start.floor] >= 1 && !flag[start.floor-k[start.floor]]){			
		    end.floor = start.floor - k[start.floor];			
			end.step = start.step +1;
			flag[end.floor] = 1;
			lift.push(end); 		
		}
	}
	//不能到达指定位置,输出-1 
	if(f == 0)
	    cout << "-1" << endl; 
}


int main(void)
{
	//输入数据 
	cin >> n >> a >> b;
	for(int i=1; i<=n; i++)
		cin >> k[i];
	
    bfs(a, b);
    
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值