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

题记:

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

扫描二维码关注公众号,回复: 3585347 查看本文章

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;
}

猜你喜欢

转载自blog.csdn.net/fyy_lufan/article/details/82972266