C ++で許可されている左、右、下、上への移動を伴う最小コストパス
2D配列があるとします。各セルが、そのセルを通過するためのコストを表す数値コストで構成されている場合、左上のセルから右下のセルへのパスを見つける必要があります。これにより、総コストが最小になります。
したがって、入力が次のような場合
32 | 10 1 | 66 | 13 | 19 |
11 | 14 | 48 | 15 8 | 7 |
10 1 | 11 14 | 17 5 | 12 | 34 |
89 | 12 5 | 42 | 21 | 14 1 |
10 0 | 33 | 11 2 | 42 | 21 |
その場合、出力は340になります(32 + 11 + 14 + 48 + 66 + 13 + 19 + 7 + 34 + 12 + 21 + 42 + 21)=340
これを解決するには、次の手順に従います-
- x、y座標、距離パラメータを使用してセルを定義します。
- サイズの配列行列を定義します:行x列。
- 行列をinfで埋める
- サイズの配列dxを定義します:4:={-1、0、1、0}
- サイズの配列dyを定義します:4:={0、1、0、-1}
- stと呼ばれるセルの1つのセットを定義します
- cell(0、0、0)をstに挿入します
- matrix [0、0]:=grid [0、0]
- (stが空ではない)間、-
- を実行します
- k:=stの最初の要素
- stの最初の要素をstから削除する
- iを初期化する場合:=0、i <4の場合、更新(iを1増やす)、実行-
- x:=k.x + dx [i]
- y:=k.y + dy [i]
- isOk(x、y)でない場合、-
- 次の部分を無視し、次の反復にスキップします
- matrix [x、y]> matrix [k.x、k.y] + grid [x、y]の場合、-
- matrix [x、y]がinfと等しくない場合、-
- stからcell(x、y、matrix [x、y])を見つけて削除します
- matrix [x、y]:=matrix [k.x、k.y] + grid [x、y]
- cell(x、y、matrix [x、y])をstに挿入します
- matrix [x、y]がinfと等しくない場合、-
- return matrix [row-1、col-1]
例
理解を深めるために、次の実装を見てみましょう-
#include <bits/stdc++.h> using namespace std; #define ROW 5 #define COL 5 class cell { public: int x, y; int distance; cell(int x, int y, int distance) : x(x), y(y), distance(distance) {} }; bool operator<(const cell& a, const cell& b) { if (a.distance == b.distance) { if (a.x != b.x) return (a.x < b.x); else return (a.y < b.y); } return (a.distance < b.distance); } bool isOk(int i, int j) { return (i >= 0 && i < COL && j >= 0 && j < ROW); } int solve(int grid[ROW][COL], int row, int col) { int matrix[row][col]; for (int i = 0; i < row; i++) for (int j = 0; j < col; j++) matrix[i][j] = INT_MAX; int dx[] = {-1, 0, 1, 0}; int dy[] = {0, 1, 0, -1}; set<cell> st; st.insert(cell(0, 0, 0)); matrix[0][0] = grid[0][0]; while (!st.empty()) { cell k = *st.begin(); st.erase(st.begin()); for (int i = 0; i < 4; i++) { int x = k.x + dx[i]; int y = k.y + dy[i]; if (!isOk(x, y)) continue; if (matrix[x][y] > matrix[k.x][k.y] + grid[x][y]){ if (matrix[x][y] != INT_MAX) st.erase(st.find(cell(x, y, matrix[x][y]))); matrix[x][y] = matrix[k.x][k.y] + grid[x][y]; st.insert(cell(x, y, matrix[x][y])); } } } return matrix[row - 1][col - 1]; } int main() { int grid[ROW][COL] = { 32, 101, 66, 13, 19, 11, 14, 48, 158, 7, 101, 114, 175, 12, 34, 89, 126, 42, 21, 141, 100, 33, 112, 42, 21 }; cout << solve(grid, ROW, COL); }
入力
{32, 101, 66, 13, 19, 11, 14, 48, 158, 7, 101, 114, 175, 12, 34, 89, 126, 42, 21, 141, 100, 33, 112, 42, 21 };
出力:
340
-
C++での最小の騎士の動き
座標が-無限大から+無限大までの無限のチェス盤があり、正方形[0、0]に騎士がいるとします。騎士は、以下に示すように、8つの可能な動きをすることができます。それぞれの動きは、基本方向に2マス、次に直交方向に1マスです。 騎士を正方形[x、y]に移動するために必要な最小ステップ数を見つける必要があります。答えが存在することが保証されています。 したがって、入力がx=5およびy=5の場合、出力は4になります。これは[0,0]→[2,1]→[4,2]→[3,4]→[のようになります。 5,5] これを解決するには、次の手順に従います- マップを定義するm Solve()とい
-
C++での演算子の優先順位
演算子の優先順位は、式内の用語のグループ化を決定します。演算子の結合性は、括弧がない場合に同じ優先順位の演算子をグループ化する方法を決定するプロパティです。これは、式の評価方法に影響します。特定の演算子は他の演算子よりも優先されます。たとえば、乗算演算子は加算演算子よりも優先されます: たとえば、x =7 + 3 * 2;ここでは、演算子*の優先順位が+よりも高いため、xには20ではなく13が割り当てられます。したがって、最初に3 * 2が乗算され、次に7に加算されます。 ここでは、優先順位が最も高い演算子が表の上部に表示され、優先順位が最も低い演算子が下部に表示されます。式内では、優先順位