BFS算法和DFS算法解决电梯问题

原文章

广度优先算法

图的遍历必须记录已经被访问的顶点,避免重复访问。

广度优先算法:借助一个队列

1.创建一个visited数组,记录已经被访问过的顶点,创建一个队列,用来存放每一层的顶点,初始化图G
2.从V0开始访问,将visited[V0]设置为true,将V0入队
3.只要队列不空,重复以下操作:
(1)队头顶点u出队。
(2)依次检查u的所有邻接顶点w,若visited[w]的值为false,则访问w,将visited[w]置为true,同时将w入队。
在这里插入图片描述
例题:奇怪的电梯
在这里插入图片描述

DFS

#include<iostream>
using namespace std;
struct A_floor{
	int isfloor;
	int able;
};
int N, S, E, result=99999; //设置为全局变量
A_floor a[200];
int temp;//全局变量便于储存当前步数 
void climb_1(int cur) {
	
	if (cur == E) {
		if (temp <= result) {
			result = temp;
		}
		return;
	}
	a[cur - 1].isfloor = 1;//我曾经来过
	temp++;
	if (a[cur - 1].able + cur <= N && a[cur + a[cur - 1].able-1].isfloor == 0)//没来过这一层
		climb_1(cur + a[cur - 1].able);
	if (cur - a[cur - 1].able >= 1 && a[cur - a[cur - 1].able-1].isfloor == 0)
		climb_1(cur - a[cur - 1].able);
	temp--; //走不下去了
	a[cur - 1].isfloor = 0;//装作没来过这里
}
int main() {
	cin >> N >> S >> E; //总楼层数,起始楼层和目标楼层
	int i;
	for (i = 0; i < N; i++){
		cin >> a[i].able;
	}
	climb_1(S);
	if (result < 99999) cout << result;
	else cout << -1;
	return 0;
}

BFS

#include<iostream>
#include<queue>
using namespace std;
int N, S, E, able[200];
bool pass[200];
struct node { 
	int id, step; 
}floor_1,floor_2;
queue<node> q;
//广度优先搜索 不需要储存temp的步数 因为第一个找到的一定是最短的
int main()
{
	cin >> N >> S >> E;
	for (int i = 1; i <= N; i++) 
		cin>>able[i];
	
	floor_1.id = S;
	floor_1.step = 0;
	q.push(floor_1);
	while (q.size())
	{
		floor_2 = q.front(); 
		q.pop();
		if (floor_2.id == E) 
			break;
		if (floor_2.id + able[floor_2.id] <= N && pass[floor_2.id + able[floor_2.id]]==0)
		{
			floor_1.id = floor_2.id + able[floor_2.id];
			floor_1.step = floor_2.step + 1;
			q.push(floor_1);
			pass[floor_2.id + able[floor_2.id]] = 1;
		}
		if (floor_2.id - able[floor_2.id] >= 1 && pass[floor_2.id - able[floor_2.id]]==0)
		{
			floor_1.id = floor_2.id - able[floor_2.id];
			floor_1.step = floor_2.step + 1;
			q.push(floor_1);
			pass[floor_2 .id - able[floor_2.id]] = 1;
		}
	}
	if (floor_2.id == E) cout << floor_2.step;
	else cout << -1;
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值