タイトルアドレス:https : //leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/
タイトルの説明
座標[0,0]から座標[m-1、n-1]まで、地面にm行n列のグリッドがあります。ロボットは座標[0、0]のグリッドから開始し、一度に1つのグリッドを左、右、上、下に移動できます(グリッドの外に移動できません)。また、行と列の座標を入力できません。数字の合計は、 kの格子。たとえば、kが18の場合、3 + 5 + 3 + 7 = 18であるため、ロボットは正方形[35、37]に入ることができます。しかし、3 + 5 + 3 + 8 = 19であるため、正方形[35、38]に入ることができません。ロボットが到達できるグリッドはいくつですか?
質問の例
例1:
入力:m = 2、n = 3、k = 1
出力:3
例2:
入力:m = 3、n = 1、k = 0
出力:1
ヒント:
1 <= n、m <= 100
0 <= k <= 20
問題解決のアイデア
行列検索の問題は、幅優先検索または深さ優先検索戦略によって解決できます。これは、左上隅から右下隅であるため、上下に移動することなく、上下に移動することによってのみ到達できるためです。
ロボットの可動範囲は、次の2つの条件を同時に満たす必要があります。
- 現在のグリッド座標の数字の合計はk以下です。
- 座標(0、0)から開始して、現在のグリッドは、上下左右に移動することで到達できます。
BFS:幅優先検索では、キューを使用して問題を解決します。検索されていない各ポイントを一度にキューに入れ、キューの先頭要素を現在通過しているノードとしてポップします。BFSがここにあり、現在までの特定のトラバーサル数を判別する必要がない場合、テンプレートは次のとおりです。
一方、(キューない空きキュー)
CUR = queue.pop()
のためのノードでCURすべての隣接ノード:
IF ノードが有効でアクセスされない:
(ノード)queue.push
現在通過しているレイヤー、つまりステップの数またはバイナリツリーのレベルを判別する必要がある場合、テンプレートは次のとおりです。
レベルlevel = 0
while (queue queue is not empty)the
number of elements in the queue size = queue.size()// the number of nodes to move to
while while(size- ){
cur = queue.pop()
forノード内の隣接の全ては、CURノード:
IF ノードがアクセス有効ではない:
queue.push(ノード)
}
層レベル ++。
この問題では、トラバースレイヤーの数を記録する必要はなく、トラバースされたポイントの数を数えるだけで済みます。visitを使用して、ポイントがトラバースされたかどうかを記録します。
DFS:深度优先搜索通过递归,先朝着一个方向搜索到底,再回溯至上个节点,沿另一个方向搜索,依次类推。在本题中,我们用数组visited来存储每个元素是否已被访问,一般的时候,我们是从上下左右四个方向行走,但分析本题可发现,从下和右两个方向前行,所以,我们最后使用dfs(x + 1, y, m, n, k) + dfs(x, y + 1, m, n, k) + 1来返回向下和向右走的数目。需要注意的一点是剪枝条件,在搜索中,遇到数位和超出目标值、此元素已访问,则应立即返回,即可行性剪枝。这里我们剪枝的条件设置为当前节点已被访问或该元素下标溢出,以及行坐标x和列坐标y的数位和(即个位+十位)大于k。
程序源码
BFS
class Solution { public: int visited[100][100]; int step = 0; int movingCount(int m, int n, int k) { for(int i = 0; i < m; i++) { for(int j = 0; j < n; j++) { visited[i][j] = 0; //初始化,所有元素均未访问 } } queue<pair<int,int>> que; que.push({0, 0}); visited[0][0] = 1; //已访问 int dir_x[] = {0, 0, -1, 1}; //x方向坐标 int dir_y[] = {-1, 1, 0, 0}; //y方向坐标 while(!que.empty()) { auto front = que.front(); que.pop(); int x = front.first; int y = front.second; step++; for(int i = 0; i < 4; i++) { int new_x = x + dir_x[i]; int new_y = y + dir_y[i]; if(new_x < 0 || new_y < 0 || visited[new_x][new_y] == 1 || new_x >= m || new_y >= n || (new_x / 10 % 10 + new_x % 10 + new_y / 10 % 10 + new_y % 10) > k) continue; que.push({new_x, new_y}); visited[new_x][new_y] = 1; } } return step; } };
DFS
class Solution { public: int visited[100][100]; int step = 0; int movingCount(int m, int n, int k) { for(int i = 0; i < m; i++) { for(int j = 0; j < n; j++) { visited[i][j] = 0; //未访问 } } return dfs(0, 0, m, n, k); } int dfs(int x, int y, int m, int n, int k) { if(visited[x][y] == 1 || x >= m || y >= n || (x / 10 % 10 + x % 10 + y / 10 % 10 + y % 10) > k) return 0; visited[x][y] = 1; //已访问 step = dfs(x + 1, y, m, n, k) + dfs(x, y + 1, m, n, k) + 1; return step; } };
参考文章