迷宫寻路(拼多多2018校招)

题目描述

假设一个探险家被困在了地底的迷宫之中,要从当前位置开始找到一条通往迷宫出口的路径。迷宫可以用一个二维矩阵组成,有的部分是墙,有的部分是路。迷宫之中有的路上还有门,每扇门都在迷宫的某个地方有与之匹配的钥匙,只有先拿到钥匙才能打开门。请设计一个算法,帮助探险家找到脱困的最短路径。如前所述,迷宫是通过一个二维矩阵表示的,每个元素的值的含义如下 0-墙,1-路,2-探险家的起始位置,3-迷宫的出口,大写字母-门,小写字母-对应大写字母所代表的门的钥匙

输入描述

迷宫的地图,用二维矩阵表示。第一行是表示矩阵的行数和列数M和N
后面的M行是矩阵的数据,每一行对应与矩阵的一行(中间没有空格)。M和N都不超过100, 门不超过10扇

输出描述

路径的长度,是一个整数。

示例1

输入:

6 10
a110000011
0021111110
11101000A0
1001100111
100B000101
11030001b1

输出: 33

算法分析

这题就是普通的bfs多了‘钥匙’这个状态
所以visit[x][y][key]的意义就是 横坐标为x,纵坐标为y,钥匙状态为key的点是否访问过
钥匙的状态 就用二进制数表示 最多10 把钥匙 那就是1024
比如我现在有第二把钥匙和第四把钥匙  那么我的钥匙状态就是 0101000000 也就是 320

BFS寻找最短路径:

#include<iostream>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<stdlib.h>

using namespace std;
int m, n;
int visit[105][105];
struct Node {
	int x, y, step;
	Node(int x, int y, int step) : x(x), y(y), step(step) {};
};

int bfs(vector<string> &str, int start_x, int start_y);
int main()
{
	cin >> m >> n;
	vector<string> str(m, string(n, ' '));
	for (int i = 0; i < m; ++i)
		for (int j = 0; j < n; ++j)
			cin >> str[i][j];

	bool flag = true;
	for (int i = 0; i < m; ++i)
	{
		if (!flag) break;
		for (int j = 0; j < n; ++j) {
			if (str[i][j] == '2')
			{
				visit[i][j] = 1;
				cout << bfs(str, i, j) << endl;
				flag = false;
				break;
			}
		}
	}
}

int bfs(vector<string> &str, int start_x, int start_y)
{
	queue<Node> que;
	que.push(Node(start_x, start_y, 0));
	vector<pair<int, int>> directs = { { 0, 1 },{ 0, -1 },{ 1, 0 },{ -1, 0 } };
	while (!que.empty()) {
		Node node = que.front();
		que.pop();
		if (str[node.x][node.y] == '3') return node.step;
		for (pair<int, int> direct : directs) {
			int x = node.x + direct.first;
			int y = node.y + direct.second;
			if (x < 0 || x >= m || y < 0 || y >= n || str[x][y] == '0') continue;

			if (visit[x][y] != 1) {
				visit[x][y] = 1;
				que.push(Node(x, y, node.step + 1));
			}
		}
	}

}

提交代码:

#include<iostream>
#include<string.h>
#include<vector>
#include<queue>
#include<map>

using namespace std;
int m, n;
int visit[105][105][1200] ;
struct Node {
	int x, y, key, step;
	Node(int x, int y, int key, int step) : x(x), y(y), key(key), step(step) {};
};

int bfs(vector<string> &str, int start_x, int start_y);
int main()
{
	cin >> m >> n;
	memset(visit, 0, sizeof(visit));
	vector<string> str(m, string(n, ' '));
	for (int i = 0; i < m; ++i)
		for (int j = 0; j < n; ++j)
			cin >> str[i][j];

	bool flag = true;
	for (int i = 0; i < m; ++i)
	{
		if (!flag) break;
		for (int j = 0; j < n; ++j) {
			if (str[i][j] == '2')
			{
				visit[i][j][0] = 1;
				cout << bfs(str, i, j) << endl;
				flag = false;
				break;
			}
		}
	}
	return 0;
}

int bfs(vector<string> &str, int start_x, int start_y)
{
	queue<Node> que;
	que.push(Node(start_x, start_y, 0, 0));
	vector<pair<int, int>> directs = { { 0, 1 },{ 0, -1 },{ 1, 0 },{ -1, 0 } };
	while (!que.empty()) {
		Node node = que.front();
		que.pop();
		if (str[node.x][node.y] == '3') return node.step;
		for (pair<int, int> direct : directs) {
			int x = node.x + direct.first;
			int y = node.y + direct.second;
            int key = node.key;
			if (x < 0 || x >= m || y < 0 || y >= n || str[x][y] == '0') continue;
			// 捡钥匙
			if (str[x][y] >= 'a' && str[x][y] <= 'z') key |= (1 << (str[x][y] - 'a'));
			// 如果没带这扇门的钥匙,就不能通过A点
			if (str[x][y] >= 'A' && str[x][y] <= 'Z' && (key & (1 << (str[x][y] - 'A'))) == 0) continue;
			// 是否带着某些钥匙走过(因此可以走回头路,但前提是去拿钥匙)
			if (visit[x][y][key] != 1) {
				visit[x][y][key] = 1;
				que.push(Node(x, y, key, node.step + 1));
			}
		}
	}
	return 0;

}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值