# 前言
刷題是本魯的硬傷。為了不讓自己刷完就忘,在此練習透過巴哈小屋輸出。
目的是為了加固自己的印象,當然能幫助到其他人的話就更好了!
# 序
這個禮拜在研究一題 :
題目的大意是叫你找出一個有障礙物的平面空間中玩家是否能將箱子推到終點
若可以的話就回傳箱子移動最少次數,反之則回傳-1
這題有趣的地方在於要把推箱子的玩家納入考量,這點造就比一般的題目多的限制與解法
# 工具
說到路徑搜索,腦袋第一個要出現的就是DFS / BFS。這兩者算是路徑搜尋的暴力解法。
DFS (Deep-First Search)
顧名思義,是深度優先搜索。以箱子移動的方向來說,不考慮阻礙物的情況下,下一步可以往四個方向延伸。在挑了一個方向後,DFS會直接往前走下去,直到確定這條路不行為止,再回推至可能可以的"岔路"換一個方向走。
每次決定路線時,可以透過設定一個演算法改變方向,就能夠將DFS改造成A*等等的進階演算法
(wiki的圖,此處是展示每次第一個方向是往左邊的策略下DFS會如何走遍Tree。第一次碰壁(4)後就回朔至有路可走的3)
這個做法以實作來說是比較容易的,因為我們可以使用函式本身的特性以遞迴的方式實作
若不想用遞迴,可以使用迴圈搭配queue來做。
BFS (Breadth-First Search)
回過頭來說,BFS則是在選擇要往哪裡走時先把同一層的步數探索完之後再繼續往下進行的。
這種做法跟筆者玩遊戲探索地圖時比較相近
不然,往同一個方向深入後萬一因為劇情等等因素無法往回探就糟糕了!
實作上不能單用函式遞迴解決,必須搭配stack這個資料結構才行。
值得一提的是BFS的解一定是最速解,所以以這題的要求,很明顯地算箱子步數時要用BFS。
## Python實作 DFS/BFS
(ref : Stacks and Queues in Python)
既然兩者都可以透過迴圈加上一個指定的資料結構解決,那此處就討論Python如何呼叫並使用stack跟queue。
以我這個不是拿Python當飯吃的人來說,只需要使用deque (發音deck) 資料結構就夠了。
# 建立deque data = deque() # 塞資料進去 data.append(somethingOne) data.append(somethingTwo) # 當作queue使用 data.popleft() # 當作stack使用 data.pop() |
一魚兩吃,且不爽哉
有了資料結構,就能實作兩種演算法了
不過實作時要注意題目提供的資料結構與限制,這部分每題都不同所以就不提供程式碼XD
# 解題思路
有了兩種演算法及兩者的優缺點後,我們就能夠來看看這題的需求
首先,題目要求箱子步數是最少的,所以就是用BFS無誤
但每次推箱子時也需要判斷玩家是否能到對應的位置,所以玩家這邊也需要BFS或是DFS
因為DFS實做容易且有很多減少判斷的變形 (ex : A*),所以通常會用DFS或其變形
# 實做
這邊我不提供解答,但可以提供我看過好的網站給各位,讓各位參考: