题目描述
地上有一个 m m m 行和 n n n 列的方格,横纵坐标范围分别为 0 ∼ m − 1 0 \sim m-1 0∼m−1 和 0 ∼ n − 1 0 \sim n-1 0∼n−1 。一个机器人从坐标 ( 0 , 0 ) (0,0) (0,0) 的格子开始移动,每一次只能向左、右、上、下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于 k k k 的格子。
请问该机器人能够到达多少格子?
样例
Input: k = 7, m = 4, n = 5
Output: 20
Input: k = 18, m = 40, n = 40
Output: 1484
解题思路
-
描述
就是使用广度优先遍历。
-
实现代码:
/* 包含头文件: #include <vector> pair<int,int>这是C++结构模板 */ int single_sum(int num) // 获取一个数各位之和 { int sum = 0; while (num) { sum += (num % 10); num = num / 10; } return sum; } int get_sum(pair<int, int> loc) // 获取横纵坐标各位之和 { return single_sum(loc.first) + single_sum(loc.second); } int movingCount(int threshold, int row, int col) { int result = 0; // 定义返回的结果变量 // 该语句创建并初始化一个二维数组,用作被访问的标志 vector<vector<bool> > visited(col, vector<bool>(col, false)); queue<pair<int, int> > queue; // 定义队列 queue.push({0,0}); int dx[] = { -1,0,1,0 }, dy[] = { 0,1,0,-1 }; // 作为访问上下左右的一种技巧 int tmpx, tmpy; pair<int, int> tmp; while (!queue.empty()) { tmp = queue.front(); queue.pop(); // 符合条件,进行深入操作 if ((get_sum(tmp) <= threshold) && (visited[tmp.first][tmp.second] == false)) { result++; visited[tmp.first][tmp.second] = true; for (int i = 0; i < 4; i++) { tmpx = tmp.first + dx[i]; tmpy = tmp.second + dy[i]; if ((tmpx >= 0) && (tmpx < row) && (tmpy >= 0) && (tmpy < col)) { queue.push({tmpx,tmpy}); } } } } return result; }
-
复杂度分析
时间复杂度: ≈ O ( n ) \approx O(n) ≈O(n)
空间复杂度: ≈ O ( c o l ∗ r o w ) \approx O(col * row) ≈O(col∗row)
使用若干辅助变量,一个vector二维数组,一个queue队列,几个临时变量。