題目描述:
給定乙個二維網格 grid。 「.」 代表乙個空房間, 「#」 代表一堵牆, 「@」 是起點,(「a」, 「b」, …)代表鑰匙,(「a」, 「b」, …)代表鎖。
我們從起點開始出發,一次移動是指向四個基本方向之一行走乙個單位空間。我們不能在網格外面行走,也無法穿過一堵牆。如果途經乙個鑰匙,我們就把它撿起來。除非我們手裡有對應的鑰匙,否則無法通過鎖。
假設 k 為鑰匙/鎖的個數,且滿足 1 <= k <= 6,字母表中的前 k 個字母在網格中都有自己對應的乙個小寫和乙個大寫字母。換言之,每個鎖有唯一對應的鑰匙,每個鑰匙也有唯一對應的鎖。另外,代表鑰匙和鎖的字母互為大小寫並按字母順序排列。
返回獲取所有鑰匙所需要的移動的最少次數。如果無法獲取所有鑰匙,返回 -1 。
示例 1:
輸入:["@.a.#","###.#",「b.a.b」]
輸出:8
示例 2:
輸入:["@…aa","…b#.","…b"]
輸出:6
1 <= grid.length <= 30
1 <= grid[0].length <= 30
grid[i][j] 只含有 『.』, 『#』, 『@』, 『a』-『f』 以及 『a』-『f』
鑰匙的數目範圍是 [1, 6],每個鑰匙都對應乙個不同的字母,正好開啟乙個對應的鎖。
方法1:
(1)使用廣度優先搜尋,配合狀態壓縮;
(2)先遍歷原陣列,找出grid中的起始點位置和總的鑰匙的個數,並將起始點的位置壓入到佇列中;
(3)佇列中元素儲存位置和當前位置的狀態,由於鑰匙最多只有6個,則鑰匙的狀態最多只有64個,故可以使用狀態壓縮,來儲存各個鑰匙在某個位置時,獲得的狀態;
(4)為了記錄之前出現過的位置的狀態,使用三維陣列來儲存從初始位置到各個位置的距離,陣列初始置為-1,來標識沒有訪問過當前位置;
class
solution
else
if(grid[i]
[j]==
'@'));
}}}//各個方向
vectorint>> next =,,
,};//三維陣列,記錄到各個位置的距離
vectorint>>
>
distance(30
, vectorint>>(30
, vector<
int>(64
,-1)
)); distance[q.
front()
[0]]
[q.front()
[1]]
[0]=
0;//初始化位置的距離
int target =(1
<< count_k)-1
;//最終所有的鑰匙都要找到,既終止位置的狀態
while
(!q.
empty()
)int cur_state = cur_pos[2]
;//當前獲得的鑰匙狀態
if(grid[next_r]
[next_c]
>=
'a'&&grid[next_r]
[next_c]
<=
'z')
}//當前位置之前沒有訪問過,則加入當前位置
if(distance[next_r]
[next_c]
[cur_state]==-
1));
}}}}
return-1
;}};
獲取所有鑰匙的最短路徑
description 給定乙個二維網格 grid。代表乙個空房間,代表一堵牆,是起點,a b 代表鑰匙,a b 代表鎖。我們從起點開始出發,一次移動是指向四個基本方向之一行走乙個單位空間。我們不能在網格外面行走,也無法穿過一堵牆。如果途經乙個鑰匙,我們就把它撿起來。除非我們手裡有對應的鑰匙,否則無...
LeetCode 864 獲取所有鑰匙的最短路徑
給定乙個二維網格grid。代表乙個空房間,代表一堵牆,是起點,a b 代表鑰匙,a b 代表鎖。我們從起點開始出發,一次移動是指向四個基本方向之一行走乙個單位空間。我們不能在網格外面行走,也無法穿過一堵牆。如果途經乙個鑰匙,我們就把它撿起來。除非我們手裡有對應的鑰匙,否則無法通過鎖。假設 k 為鑰匙...
NCSTOJ 獲取所有鑰匙的最短路徑
e 獲取所有鑰匙的最短路徑 time limit 2 sec memory limit 128 mib back submit edit description 給定乙個二維網格 grid。代表乙個空房間,代表一堵牆,是起點,a b 代表鑰匙,a b 代表鎖。我們從起點開始出發,一次移動是指向四個基...