今天刷華為機試題,刷到一道迷宮問題,看了其他人提交的**發現有許多小bug不是很滿意,我這裡就用回溯法解決了這個迷宮問題,配上**講解
題目:定義乙個二維陣列n*m(其中2<=n<=10;2<=m<=10),如5 × 5陣列下所示:
int maze[5][5] = ;
它表示乙個迷宮,其中的1表示牆壁,0表示可以走的路,只能橫著走或豎著走,不能斜著走,要求程式設計序找出從左上角到右下角的最短路線。入口點為[0,0],既第一空格是可以走的路。
input
乙個n × m的二維陣列,表示乙個迷宮。資料保證有唯一解,不考慮有多解的情況,即迷宮只有一條通道。
output
左上角到右下角的最短路徑
1、回溯法基本思想
回溯法是一種選優搜尋法,按選優條件向前搜尋,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇。
3、**
deals=
[lambda x,y:
(x+1
,y),
#向下lambda x,y:
(x,y+1)
,#向右
lambda x,y:
(x-1
,y),
#向上lambda x,y:
(x,y-1)
,#向左
]def
deal_maze
(start,end,maze)
: path=
#走過的路徑
maze[0]
[0]=
2#走過的路徑記為2
while
len(path)
>0:
curnode=path[-1
]if curnode[0]
==end[0]
and curnode[1]
==end[1]
:print
('到達終點'
)for i in path:
print
(i)return
true
for deal in deals:
nextnode=deal(curnode[0]
,curnode[1]
)if0<=nextnode[0]
<=end[0]
and0
<=nextnode[1]
<=end[1]
:#判斷沒有出迷宮
if maze[nextnode[0]
][nextnode[1]
]==0:
maze[nextnode[0]
][nextnode[1]
]=2break
else
: path.pop(
)else
:print
('沒有路'
)return
false
while
true
:[a,b]
=list
(map
(int
,input()
.split())
)#a為行,b為列
maze=
#迷宮本身
for i in
range
(a):
[int
(j)for j in
input()
.split()]
) deal_maze((0
,0),
(a-1
,b-1
),maze)
輸入:
5 50 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
輸出:到達終點
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)
4、while/for…else解釋
**裡面的while迴圈和for迴圈後面加了else
for, while迴圈如果在計數器用盡跳出時,用不用else語句對結果都是沒有影響的,所以只有在for, while迴圈非正常結束時,才會體現出效果,比如:通過break跳出迴圈,這時也會跳過else語句塊,直接執行else之後的語句。可以在else語句塊中寫一些不通過break語句跳出時才執行的**
用回溯法求解跳馬問題
演算法描述 乙隻馬在棋盤的某一點,它可以朝8個方向前進,方向向量分別是 2,1 2,1 1,2 1,2 2,1 2,1 1,2 1,2 從中任選擇乙個方向前進,到達新的位置。在從新的位置選擇乙個方向前進,繼續,直到無法前進為止。無法前進可能有如下原因 下一位置超出邊界 下一位置已經被訪問過。當馬已經...
回溯法求解迷宮問題
題目 這是我在老師發的ppt上發現的一道題,如下 1表示起點 7表示終點,一共六個路口,每個路口可以通達最多左上右三個路口,不能走的方向用0表示,求從1到7的路徑。求解思路 每個路口最多有三個搜尋分支。把演算法設計為如下的搜尋過程 把整個搜尋分解為向左 向前和向右三個方向上子問題的搜尋。當搜尋到某個...
回溯法求解迷宮問題
最近在leetcode上看了些演算法題,有些看著很簡單的很常用的東西,竟然一下子想不出來怎麼求解,比如說 實現sqrt函式,求陣列的排列。如果高數學的不好,這些看似簡單的問題,第一次碰到也會感覺很難求解,當然了,今天要說的是這樣乙個問題,求解迷宮的所有解,這個問題的求解用到了回溯法的思想,不了解這個...