讓我們一起來玩掃雷遊戲!
給定乙個代表遊戲板的二維字元矩陣。 'm' 代表乙個未挖出的地雷,'e' 代表乙個未挖出的空方塊,'b' 代表沒有相鄰(上,下,左,右,和所有4個對角線)地雷的已挖出的空白方塊,數字('1' 到 '8')表示有多少地雷與這塊已挖出的方塊相鄰,'x' 則表示乙個已挖出的地雷。
如果乙個地雷('m')被挖出,遊戲就結束了- 把它改為'x'。
如果乙個沒有相鄰地雷的空方塊('e')被挖出,修改它為('b'),並且所有和其相鄰的方塊都應該被遞迴地揭露。
如果乙個至少與乙個地雷相鄰的空方塊('e')被挖出,修改它為數字('1'到'8'),表示相鄰地雷的數量。
如果在此次點選中,若無更多方塊可被揭露,則返回面板。
示例 1:
輸入:
[['e', 'e', 'e', 'e', 'e'],
['e', 'e', 'm', 'e', 'e'],
['e', 'e', 'e', 'e', 'e'],
['e', 'e', 'e', 'e', 'e']]
click : [3,0]
輸出:
[['b', '1', 'e', '1', 'b'],
['b', '1', 'm', '1', 'b'],
['b', '1', '1', '1', 'b'],
['b', 'b', 'b', 'b', 'b']]
示例 2:
輸入:
[['b', '1', 'e', '1', 'b'],
['b', '1', 'm', '1', 'b'],
['b', '1', '1', '1', 'b'],
['b', 'b', 'b', 'b', 'b']]
click : [1,2]
輸出:
[['b', '1', 'e', '1', 'b'],
['b', '1', 'x', '1', 'b'],
['b', '1', '1', '1', 'b'],
['b', 'b', 'b', 'b', 'b']]
注意:
輸入矩陣的寬和高的範圍為 [1,50]。
點選的位置只能是未被挖出的方塊 ('m' 或者 'e'),這也意味著面板至少包含乙個可點選的方塊。
輸入面板不會是遊戲結束的狀態(即有地雷已被挖出)。
簡單起見,未提及的規則在這個問題中可被忽略。例如,當遊戲結束時你不需要挖出所有地雷,考慮所有你可能贏得遊戲或標記方塊的情況。
理解題意並不複雜,典型的搜尋題,深搜廣搜都可以,**為廣搜:
from queue import queue
from pprint import pprint
# bfs
# time: o(mn), space: o(mn), m n表示輸入陣列行列數
class solution:
def get_cnt(self, next, x, y, rows, columns, board):
'''獲取周圍炸彈個數'''
cnt = 0
for i in range(8):
tx = x + next[i][0]
ty = y + next[i][1]
if 0 <= tx < rows and 0 <= ty < columns and board[tx][ty] == 'm':
cnt += 1
return cnt
def updateboard(self, board, click):
if not board:
return board
if board[click[0]][click[1]] == 'm':
board[click[0]][click[1]] = 'x'
return board
rows, columns = len(board), len(board[0])
next = [
[0, 1],
[1, 0],
[0, -1],
[-1, 0],
[1, 1], # 右下
[1, -1],
[-1, -1],
[-1, 1]
]# 點選的位置周圍有炸彈,修改為炸彈數量,結束
cnt = self.get_cnt(next, click[0], click[1], rows, columns, board)
if cnt:
board[click[0]][click[1]] = str(cnt)
return board
q = queue()
q.put(click)
board[click[0]][click[1]] = 'b'
while not q.empty():
x, y = q.get()
for i in range(8):
tx = x + next[i][0]
ty = y + next[i][1]
if 0 <= tx < rows and 0 <= ty < columns and board[tx][ty] == 'e':
cnt = self.get_cnt(next, tx, ty, rows, columns, board) # 周圍炸彈個數
if not cnt:
board[tx][ty] = 'b'
q.put([tx, ty])
else:
board[tx][ty] = str(cnt) # 周圍有炸彈,修改為炸彈數量,不計入佇列
return board
# [["b", "b", "b", "b", "b", "b", "1", "1"],
# ["b", "1", "1", "1", "b", "b", "1", "m"],
# ["1", "2", "m", "1", "b", "b", "1", "1"],
# ["m", "2", "1", "1", "b", "b", "b", "b"],
# ["1", "1", "b", "b", "b", "b", "b", "b"],
# ["b", "b", "b", "b", "b", "b", "b", "b"],
# ["b", "1", "2", "2", "1", "b", "b", "b"],
# ["b", "1", "m", "m", "1", "b", "b", "b"]]
s = solution()
ans = s.updateboard([["b", "b", "b", "b", "b", "b", "1", "e"],
["b", "1", "1", "1", "b", "b", "1", "m"],
["1", "2", "m", "1", "b", "b", "1", "1"],
["m", "2", "1", "1", "b", "b", "b", "b"],
["1", "1", "b", "b", "b", "b", "b", "b"],
["b", "b", "b", "b", "b", "b", "b", "b"],
["b", "1", "2", "2", "1", "b", "b", "b"],
["b", "1", "m", "m", "1", "b", "b", "b"]],
[0, 7])
# ans = s.updateboard([['e', 'e', 'e', 'e', 'e'],
# ['e', 'e', 'm', 'e', 'e'],
# ['e', 'e', 'e', 'e', 'e'],
# ['e', 'e', 'e', 'e', 'e']], [3, 0])
pprint(ans)
廣搜和深搜
一般來說,廣搜常用於找單一的最短路線,或者是規模小的路徑搜尋,它的特點是 搜到就是最優解 而深搜用於找多個解或者是 步數 已知 好比3步就必需達到前提 的標題,它的空間效率高,然則找到的不必定是最優解,必需記實並完成全數搜尋,故一般情況下,深搜需要很是高效的剪枝 優化 像搜尋最短路徑這些的很顯著若是...
搜尋(深搜 廣搜)
我記得在遙遠的2017年,我會敲的搜尋也只有暴力列舉了。那個時候的我深搜剛會一丟丟,所以也只配切切水題,然而經常死迴圈re那是肯定的。如今的我因為在多次比賽中都死於搜尋,那就必須得認真磕一下了。其實是這樣的 我眼裡認為的暴力就真的只是暴力,暴力無非就兩種 列舉打表和模擬。然而在這麼多次比賽後,我總能...
深搜和廣搜
深度優先搜尋屬於圖演算法的一種,英文縮寫為dfs即depth first search.其過程簡要來說是對每乙個可能的分支路徑深入到不能再深入為止,而且每個節點只能訪問一次 採用的搜尋方法的特點是盡可能先對縱深方向進行搜尋。基本思路 深度優先遍歷圖的方法是,從圖中某頂點v出發 1 訪問頂點v 2 依...