12.机器人的运动范围
地上有一个 m 行和 n 列的方格,横纵坐标范围分别是0∼m−1 和 0∼n−1。
一个机器人从坐标 (0,0) 的格子开始移动,每一次只能向左,右,上,下四个方向移动一格。
但是不能进入行坐标和列坐标的数位之和大于 k 的格子。
请问该机器人能够达到多少个格子?
注意:
- 0<=m<=50
- 0<=n<=50
- 0<=k<=100
样例1:
输入:k=7, m=4, n=5
输出:20
样例2:
输入:k=18, m=40, n=40
输出:1484
解释:当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。
代码:
class Solution {
//定义四个方向的移动:上、右、下、左
int[][] dir = {{-1,0},{0,1},{1,0},{0,-1}};
//标记矩阵中的位置是否已经访问过
boolean[][] vis;
//记录可达的格子数量
int res;
public int movingCount(int threshold, int rows, int cols)
{
//如果行数或列数为0,直接返回0
if(rows == 0 || cols == 0)return 0;
//初始化访问标记矩阵
vis = new boolean[rows][cols];
//使用队列进行广度优先搜索
Queue<int[]>queue = new LinkedList<>();
//从起点(0,0)开始
queue.add(new int[]{0,0});
//标记起点已访问
vis[0][0] = true;
//BFS循环
while(!queue.isEmpty()){
//取出队列中当前元素
int[] t = queue.remove();
int x = t[0];
int y = t[1];
//每访问一个格子,结果+1
res++;
//遍历四个方向
for(int i = 0;i<4;i++){
int x1 = x + dir[i][0];
int y1 = y + dir[i][1];
//检查新坐标是否在矩阵范围内且未被访问过
if(x1>=0&&x1<rows&&y1>=0&&y1<cols&&!vis[x1][y1]){
//检查坐标的数位和是否小于等于阈值
if(cal(x1,y1)<=threshold){
//标记为已访问
vis[x1][y1] = true;
//加入队列继续搜索
queue.add(new int[]{x1,y1});
}
}
}
}
//返回结果
return res;
}
//计算坐标(x,y)的数位和
public int cal(int x,int y){
int temp = 0;
while(x>0){
temp+=x%10;
x/=10;
}
while(y>0){
temp+=y%10;
y/=10;
}
return temp;
}
}