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