拼多多2018暑期實習招聘線上程式設計題:迷宮尋路
題目描述:一個探險家被困在地底迷宮中,要從當前位置開始找一條通往迷宮出口的路徑。迷宮用一個二維矩陣表示,有的部分是牆,有的部分是路。迷宮之中有的路上還有門,每扇門都在迷宮的某個地方有與之匹配的鑰匙,只有先拿到鑰匙才能開啟門。請幫探險家找到脫困的最短路徑。二維矩陣中,0表示牆,1表示路,2表示起始位置,3表示迷宮出口。大寫字母表示門,小寫字母對應大寫字母所代表的門的鑰匙。
輸入描述:
迷宮的地圖,用二維矩陣表示。第一行是矩陣的行數和列數M和N。後面的M行是矩陣的資料,每一行對應矩陣的一行(中間沒有空格)。M和N都不超過100,門不超過10扇。
輸出描述:路徑的長度,是一個整數。
輸入:
5 5
02111
01a0A
01003
0101B
0b111
輸出:
7
說明:
輸出7,對應的路徑為:(0,1)、(0,2)、(1,2)、(0,2)、(0,3)、(0,4)、(1,4)、(2,4)。無需輸出路徑
走迷宮問題在一般情況下都要求形成一個簡單路徑,也就是說,同一個通道在路徑上最多隻能出現1次。但是這道題不能這樣,因為有時候可能需要到某個地方尋找鑰匙,這樣就需要走回頭路(比如例題中的解答)。這裡要把條件放寬,變成:“同一個通道在路徑上最多可以出現兩次”。
這道題就是典型的迷宮尋路問題,只是有一點小變化:穿過門需要對應的鑰匙。其實很好辦:用一個字串(姑且把它視為鑰匙串)。如果路上遇到鑰匙,就將這把鑰匙加進鑰匙串中。遇到門時,如果鑰匙串中有能開啟這扇門的鑰匙,就可以通過,否則無法通過(視為牆壁)。
下面是我的C++程式碼。為了方便起見,就不按照線上程式設計的要求進行多次重複輸入驗證了,只測試一個輸入。
#include <iostream>
#include <vector>
#include <string>
using namespace std;
void search(const vector<string>& matrix, vector<vector<int>> left, int& result,int startx, int starty, int endx, int endy,string keys, int count, int m, int n) {
if (startx == endx && starty == endy) {
//到達終點
if (count < result) result = count;
}
else {
//從起點往四個方向搜尋
vector<vector<int>> tmpleft;
string tmpkeys;
if (startx + 1 < m && left[startx + 1][starty] > 0) {
if (matrix[startx + 1][starty] == '1' || matrix[startx + 1][starty] == '2' || matrix[startx + 1][starty] == '3') {
//是一條普通的可以走通的路,或者到達終點
tmpleft = left;
tmpleft[startx + 1][starty] -= 1;
search(matrix, tmpleft, result, startx + 1, starty, endx, endy, keys, count + 1, m, n);
}
else if (matrix[startx + 1][starty] >= 'a'&& matrix[startx + 1][starty] <= 'z') {
//路上有鑰匙
tmpleft = left;
tmpleft[startx + 1][starty] -= 1;
tmpkeys = keys;
//撿起鑰匙
tmpkeys.push_back(matrix[startx + 1][starty]);
search(matrix, tmpleft, result, startx + 1, starty, endx, endy, tmpkeys, count + 1, m, n);
}
else if (matrix[startx + 1][starty] >= 'A'&& matrix[startx + 1][starty] <= 'Z') {
//遇到一扇門
//檢查自己有沒有這扇門的鑰匙
char door = matrix[startx + 1][starty], keytoopen = door - 'A' + 'a';
int index = keys.find(keytoopen);
if (index>= 0) {
//只有找到鑰匙才能繼續往前走
tmpleft = left;
tmpleft[startx + 1][starty] -= 1;
search(matrix, tmpleft, result, startx + 1, starty, endx, endy, keys, count + 1, m, n);
}
}
}
if (startx - 1 >= 0 && left[startx - 1][starty] > 0) {
if (matrix[startx - 1][starty] == '1' || matrix[startx - 1][starty] == '2' || matrix[startx - 1][starty] == '3') {
//是一條普通的可以走通的路,或者到達終點
tmpleft = left;
tmpleft[startx - 1][starty] -= 1;
search(matrix, tmpleft, result, startx - 1, starty, endx, endy, keys, count + 1, m, n);
}
else if (matrix[startx - 1][starty] >= 'a'&& matrix[startx - 1][starty] <= 'z') {
//路上有鑰匙
tmpleft = left;
tmpleft[startx - 1][starty] -= 1;
tmpkeys = keys;
//撿起鑰匙
tmpkeys.push_back(matrix[startx - 1][starty]);
search(matrix, tmpleft, result, startx - 1, starty, endx, endy, tmpkeys, count + 1, m, n);
}
else if (matrix[startx - 1][starty] >= 'A'&& matrix[startx - 1][starty] <= 'Z') {
//遇到一扇門
//檢查自己有沒有這扇門的鑰匙
char door = matrix[startx - 1][starty], keytoopen = door - 'A' + 'a';
int index = keys.find(keytoopen);
if (index >= 0) {
//只有找到鑰匙才能繼續往前走
tmpleft = left;
tmpleft[startx - 1][starty] -= 1;
search(matrix, tmpleft, result, startx - 1, starty, endx, endy, keys, count + 1, m, n);
}
}
}
if (starty + 1 < n && left[startx][starty + 1] > 0) {
if (matrix[startx][starty + 1] == '1' || matrix[startx][starty + 1] == '2' || matrix[startx][starty + 1] == '3') {
//是一條普通的可以走通的路,或者到達終點
tmpleft = left;
tmpleft[startx][starty + 1] -= 1;
search(matrix, tmpleft, result, startx, starty + 1, endx, endy, keys, count + 1, m, n);
}
else if (matrix[startx][starty + 1] >= 'a'&& matrix[startx][starty + 1] <= 'z') {
//路上有鑰匙
tmpleft = left;
tmpleft[startx][starty + 1] -= 1;
tmpkeys = keys;
//撿起鑰匙
tmpkeys.push_back(matrix[startx][starty + 1]);
search(matrix, tmpleft, result, startx, starty + 1, endx, endy, tmpkeys, count + 1, m, n);
}
else if (matrix[startx][starty + 1] >= 'A'&& matrix[startx][starty + 1] <= 'Z') {
//遇到一扇門
//檢查自己有沒有這扇門的鑰匙
char door = matrix[startx][starty + 1], keytoopen = door - 'A' + 'a';
int index = keys.find(keytoopen);
if (index >= 0) {
//只有找到鑰匙才能繼續往前走
tmpleft = left;
tmpleft[startx][starty + 1] -= 1;
search(matrix, tmpleft, result, startx, starty + 1, endx, endy, keys, count + 1, m, n);
}
}
}
if (starty - 1 >= 0 && left[startx][starty - 1] > 0) {
if (matrix[startx][starty - 1] == '1'|| matrix[startx][starty - 1] == '2' || matrix[startx][starty - 1] == '3') {
//是一條普通的可以走通的路,或者到達終點
tmpleft = left;
tmpleft[startx][starty - 1] -= 1;
search(matrix, tmpleft, result, startx, starty - 1, endx, endy, keys, count + 1, m, n);
}
else if (matrix[startx][starty - 1] >= 'a'&& matrix[startx][starty - 1] <= 'z') {
//路上有鑰匙
tmpleft = left;
tmpleft[startx][starty - 1] -= 1;
tmpkeys = keys;
//撿起鑰匙
tmpkeys.push_back(matrix[startx][starty - 1]);
search(matrix, tmpleft, result, startx, starty - 1, endx, endy, tmpkeys, count + 1, m, n);
}
else if (matrix[startx][starty - 1] >= 'A'&& matrix[startx][starty - 1] <= 'Z') {
//遇到一扇門
//檢查自己有沒有這扇門的鑰匙
char door = matrix[startx][starty - 1], keytoopen = door - 'A' + 'a';
int index = keys.find(keytoopen);
if (index >= 0) {
//只有找到鑰匙才能繼續往前走
tmpleft = left;
tmpleft[startx][starty - 1] -= 1;
search(matrix, tmpleft, result, startx, starty - 1, endx, endy, keys, count + 1, m, n);
}
}
}
}
}
int main()
{
//輸入迷宮
int m, n;
cin >> m >> n;
int startx, starty, endx, endy;
vector<string> matrix(m);
vector<vector<int>> left(m);
for (int i = 0; i < m; i++) {
cin >> matrix[i];
for (int j = 0; j < n; j++) {
if (matrix[i][j] == '0') left[i].push_back(0);
else left[i].push_back(2);
if (matrix[i][j] == '2') {
startx = i, starty = j;
}
if (matrix[i][j] == '3') {
endx = i, endy = j;
}
}
}
left[startx][starty] = 1;
string keys = "";
int res = INT_MAX;
search(matrix, left, res, startx, starty, endx, endy, keys, 0, m, n);
cout << res << endl;
system("pause");
return 0;
}
相關文章
- 【Javascript + Vue】實現對任意迷宮圖片的自動尋路JavaScriptVue
- 基於深度強化學習(DQN)的迷宮尋路演算法強化學習演算法
- Python專案實戰:20行程式設計迷宮大陣Python行程程式設計
- PHP 生成迷宮路線PHP
- 尋路者華為雲:在產業AI迷宮裡走直線產業AI
- golang學習筆記——迷宮的廣度優先搜尋Golang筆記
- POJ3984-迷宮問題
- 回溯法求迷宮問題
- 基於RL(Q-Learning)的迷宮尋路演算法演算法
- 迷宮問題——最短程式碼,不到70行
- 走迷宮
- dfs深度優先搜尋解決迷宮類問題(遍歷)
- 華為優招面試題---迷宮問題面試題
- 解密迷宮問題:三種高效演算法Java實現,讓你輕鬆穿越未知迷宮解密演算法Java
- 基於JavaFX圖形介面演示的迷宮建立與路徑尋找Java
- 回溯法解決迷宮問題
- 迷宮問題【資料結構實驗報告】資料結構
- 509迷宮
- 如何用程式解圖片迷宮?
- (C++)資料結構實驗二——迷宮問題C++資料結構
- 回溯和遞迴實現迷宮問題(C語言)遞迴C語言
- 「Golang成長之路」迷宮的廣度優先搜尋Golang
- PARL原始碼走讀——使用策略梯度演算法求解迷宮尋寶問題原始碼梯度演算法
- 微軟暑期實習筆試題微軟筆試
- 用C語言解決迷宮問題C語言
- # 計算機軟體技術實習日誌專案三(二) 迷宮專案實現計算機
- 簡單介紹Python迷宮生成和迷宮破解演算法Python演算法
- 【面試】如何找到迷宮出口面試
- 【dawn·資料結構】迷宮問題(C++)資料結構C++
- [SDOI2012] 走迷宮 題解
- 【Javascript + Vue】實現隨機生成迷宮圖片JavaScriptVue隨機
- C++實現迷宮的生成與解決C++
- 人才招聘季海報設計!線上網頁輕鬆設計招聘海報!網頁
- 程式設計題:尋找木頭程式設計
- 洛谷 p1605 迷宮問題 詳解
- 使用A*演算法解迷宮最短路徑問題演算法
- 試題集—— 演算法提高 學霸的迷宮演算法
- 看雪CTF.TSRC 2018 團隊賽 第十二題『移動迷宮』 解題思路