864 獲取所有鑰匙的最短路徑

2021-10-12 17:39:44 字數 1827 閱讀 4149

題目描述:

給定乙個二維網格 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 代表鎖。我們從起點開始出發,一次移動是指向四個基...