生活随笔
收集整理的這篇文章主要介紹了
LeetCode 1210. 穿过迷宫的最少移动次数(状态压缩BFS)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
1. 題目
你還記得那條風靡全球的貪吃蛇嗎?
我們在一個 n*n 的網格上構建了新的迷宮地圖,蛇的長度為 2,也就是說它會占去兩個單元格。
蛇會從左上角((0, 0) 和 (0, 1))開始移動。
我們用 0 表示空單元格,用 1 表示障礙物。
蛇需要移動到迷宮的右下角((n-1, n-2) 和 (n-1, n-1))。
每次移動,蛇可以這樣走:
-
如果沒有障礙,則向右移動一個單元格。并仍然保持身體的水平/豎直狀態。
-
如果沒有障礙,則向下移動一個單元格。并仍然保持身體的水平/豎直狀態。
-
如果它處于水平狀態并且其下面的兩個單元都是空的,就順時針旋轉 90 度。蛇從((r, c)、(r, c+1))移動到 ((r, c)、(r+1, c))。
-
如果它處于豎直狀態并且其右面的兩個單元都是空的,就逆時針旋轉 90 度。蛇從((r, c)、(r+1, c))移動到((r, c)、(r, c+1))。
返回蛇抵達目的地所需的最少移動次數。
如果無法到達目的地,請返回 -1。
示例 1:
輸入:grid
= [[0,0,0,0,0,1],[1,1,0,0,1,0],[0,0,0,0,1,1],[0,0,1,0,1,0],[0,1,1,0,0,0],[0,1,1,0,0,0]]
輸出:
11
解釋:
一種可能的解決方案是
[右
, 右
, 順時針旋轉
, 右
, 下
, 下
, 下
, 下
, 逆時針旋轉
, 右
, 下
]。示例
2:
輸入:grid
= [[0,0,1,1,1,1],[0,0,0,0,1,1],[1,1,0,0,0,1],[1,1,1,0,0,1],[1,1,1,0,0,1],[1,1,1,0,0,0]]
輸出:
9提示:
2 <= n
<= 100
0 <= grid
[i
][j
] <= 1
蛇保證從空單元格開始出發。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/minimum-moves-to-reach-target-with-rotations
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
2. 解題
- 把尾巴的坐標 x,y 還有方向 d,三個信息編碼成101進制數
- 然后蛇可以三種走法:前進、整體平移、繞尾巴旋轉
class Solution {vector
<vector
<int>> dir
= {{0,1}, {1,0}};int n
;
public:int minimumMoves(vector
<vector
<int>>& grid
) {n
= grid
.size();if(grid
[n
-1][n
-2] || grid
[n
-1][n
-1])return -1;int state
, nt
, pos
, d
, nd
, i
, j
, k
, x
, y
, x1
, y1
, x2
, y2
;queue
<int> q
;unordered_set
<int> vis
;q
.push(0);int step
= 0, size
;int target
= (101*(n
-1)+(n
-2))*101;while(!q
.empty()){size
= q
.size();while(size
--){state
= q
.front();q
.pop();if(state
== target
)return step
;d
= state
%101;pos
= state
/101;i
= pos
/101;j
= pos
%101;x
= i
+dir
[d
][0];y
= j
+dir
[d
][1];x1
= i
+dir
[d
][0];y1
= j
+dir
[d
][1];x2
= x
+ dir
[d
][0];y2
= y
+ dir
[d
][1];nt
= (101*x1
+y1
)*101+d
;if(ok(x2
, y2
) && grid
[x2
][y2
]== 0&& !vis
.count(nt
)){vis
.insert(nt
);q
.push(nt
);}nd
= d
== 0 ? 1 : 0;x1
= i
+dir
[nd
][0];y1
= j
+dir
[nd
][1];x2
= x
+ dir
[nd
][0];y2
= y
+ dir
[nd
][1];nt
= (101*x1
+y1
)*101+d
;if(ok(x1
, y1
) && grid
[x1
][y1
]==0 && ok(x2
, y2
) && grid
[x2
][y2
]== 0&& !vis
.count(nt
)){vis
.insert(nt
);q
.push(nt
);}nt
= state
/101*101 + nd
;if(ok(x1
, y1
) && grid
[x1
][y1
]==0 && ok(x2
, y2
) && grid
[x2
][y2
]== 0&& !vis
.count(nt
)){vis
.insert(nt
);q
.push(nt
);}}step
++;}return -1;}bool ok(int x
, int y
){return x
>=0 && x
< n
&& y
>=0 && y
<n
;}
};
132 ms 17.5 MB
我的CSDN博客地址 https://michael.blog.csdn.net/
長按或掃碼關注我的公眾號(Michael阿明),一起加油、一起學習進步!
總結
以上是生活随笔為你收集整理的LeetCode 1210. 穿过迷宫的最少移动次数(状态压缩BFS)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。