C++のMazeII
空のスペースと壁のある迷路の中にボールがあるとします。これで、ボールは上、下、左、右などの任意の方向に転がることで空のパスを通過できますが、壁にぶつかるまで転がりが止まりません。ボールが止まると、次の方向を選択できます。
ボールの位置、目的地、迷路を開始する必要があります。ボールが目的地に停止するための最短距離を見つける必要があります。ここで、距離は実際にはボールで覆われている空のセルの数によって定義されます(開始位置を除く、開始位置を含む)。それが目的地でボールを止めることが不可能な場合は、-1を返します。
迷路は1つの2D配列で表されます。ここで、1は壁を示し、0は空きスペースを示します。迷路の境界はすべて壁です。開始座標と宛先座標は、行と列のインデックスで表されます。
したがって、入力が2D配列で表される迷路のようなものである場合
0 | 0 | 1 | 0 | 0 |
0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 1 | 0 |
1 | 1 | 0 | 1 | 1 |
0 | 0 | 0 | 0 | 0 |
開始位置は(0、4)、宛先位置は(4、4)で、出力は12になります。1つの可能な方法は、左から下、左、下、右、下、右です。 (1 + 1 + 3 + 1 + 2 + 2 + 2)=12
これを解決するには、次の手順に従います-
-
n:=行数、m:=列数
-
ret:=無限大
-
次数nxm
の2D配列distを1つ定義します。 -
1つのキューを定義するq
-
qに開始を挿入
-
dist [start [0]、start [1]]:=0
-
(qが空ではない)間、-
-
curr:=qの最初の要素
-
qから要素を削除
-
x:=curr [0]、y:=curr [1]
-
xがdestination[0]と同じで、yがdestination [1]と同じである場合、-
-
ret:=retとdist[x、y]
の最小値
-
-
currDist:=dist [x、y]
-
tempDist:=0
-
i:=x
-
(i +1
-
(iを1増やします)
-
(tempDistを1増やします)
-
-
currDist + tempDist
-
dist [i、y]:=currDist + tempDist
-
{i、y}をq
に挿入します
-
-
i:=x
-
tempDist:=0
-
(i --1>=0かつgrid[i-1、y]がゼロの場合)、do-
-
(tempDistを1増やします)
-
(iを1減らします)
-
-
currDist + tempDist*ltの場合; dist [i、y]、次に-
-
dist [i、y]:=currDist + tempDist
-
{i、y}をq
に挿入します
-
-
i:=y
-
tempDist:=0
-
(i --1> =0でgrid[x、i --1]がゼロの場合)、do-
-
(iを1減らします)
-
(tempDistを1増やします)
-
-
currDist + tempDist
-
dist [x、i]:=currDist + tempDist
-
{x、i}をq
に挿入します
-
-
i:=y
-
tempDist:=0
-
(i + 1
-
(iを1増やします)
-
(tempDistを1増やします)
-
-
currDist + tempDist
-
dist [x、i]:=currDist + tempDist
-
{x、i}をq
に挿入します
-
-
-
return(retがinfと同じ場合は-1、それ以外の場合はret)
例
理解を深めるために、次の実装を見てみましょう-
#include <bits/stdc++.h> using namespace std; class Solution { public: int shortestDistance(vector<vector<int<>& grid, vector<int<& start, vector<int<& destination) { int n = grid.size(); int m = n? grid[0].size() : 0; int ret = INT_MAX; vector < vector <int< > dist(n, vector <int<(m, INT_MAX)); queue < vector <int< > q; q.push(start); dist[start[0]][start[1]] = 0; while(!q.empty()){ vector <int< curr = q.front(); q.pop(); int x = curr[0]; int y = curr[1]; if(x == destination[0] && y == destination[1]){ ret = min(ret, dist[x][y]); } int currDist = dist[x][y]; int tempDist = 0; int i = x; while(i + 1 < n && !grid[i + 1][y]){ i++; tempDist++; } if(currDist + tempDist < dist[i][y]){ dist[i][y] = currDist + tempDist; q.push({i, y}); } i = x; tempDist = 0; while(i - 1 >= 0 && !grid[i - 1][y]){ tempDist++; i--; } if(currDist + tempDist < dist[i][y]){ dist[i][y] = currDist + tempDist; q.push({i, y}); } i = y; tempDist = 0; while(i - 1 >= 0 && !grid[x][i - 1]){ i--; tempDist++; } if(currDist + tempDist < dist[x][i]){ dist[x][i] = currDist + tempDist; q.push({x, i}); } i = y; tempDist = 0; while(i + 1 < m && !grid[x][i + 1]){ i++; tempDist++; } if(currDist + tempDist < dist[x][i]){ dist[x][i] = currDist + tempDist; q.push({x, i}); } } return ret == INT_MAX ? - 1 : ret; }; main(){ Solution ob; vector<vector<int<> v = {{0,0,1,0,0},{0,0,0,0,0},{0,0,0,1,0},{1,1,0,1,1},{0,0,0,0,0}}; vector<int< v1 = {0,4}, v2 = {4,4}; cout << (ob.shortestDistance(v, v1, v2)); }
入力
{{0,0,1,0,0},{0,0,0,0,0},{0,0,0,1,0},{1,1,0,1,1},{0,0,0,0,0}}, {0,4},{4,4}
出力
12
-
C++の迷路
空のスペースと壁のある迷路の中にボールがあるとします。これで、ボールは上、下、左、右などの任意の方向に転がることで空のパスを通過できますが、壁にぶつかるまで転がりが止まりません。ボールが止まると、次の方向を選択できます。 ボールの位置、目的地、迷路を開始し、ボールが目的地に止まるかどうかを確認する必要があります。迷路は1つの2D配列で表されます。ここで、1は壁を示し、0は空きスペースを示します。迷路の境界はすべて壁です。開始座標と宛先座標は、行と列のインデックスで表されます。 したがって、入力が2D配列で表される迷路のようなものである場合 0 0 1 0 0
-
C++のMazeIII
空のスペースと壁のある迷路があり、その迷路の中にボールもあるとします。ボールは、上(u)、下(d)、左(l)、または右(r)の方向に転がることで空きスペースを通過できますが、壁にぶつかるまで転がり続けます。ボールが止まると、次の方向を選ぶことができます。その迷路にも1つの穴があります。ボールが穴に転がると、ボールは穴に落ちます。 したがって、ボールの位置、穴の位置、迷路がある場合、最短距離を移動することでボールがどのように穴に落ちるかを調べる必要があります。ここで、距離は、ボールがスタート(除外)からホール(含まれる)まで移動した空きスペースの数によって定義されます。 「u」、「d」、「l