首页 > 试题广场 >

机器人的运动范围

[编程题]机器人的运动范围
  • 热度指数:460402 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
地上有一个 rows 行和 cols 列的方格。坐标从 [0,0] 到 [rows-1,cols-1] 。一个机器人从坐标 [0,0] 的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于 threshold 的格子。 例如,当 threshold 为 18 时,机器人能够进入方格   [35,37] ,因为 3+5+3+7 = 18。但是,它不能进入方格 [35,38] ,因为 3+5+3+8 = 19 。请问该机器人能够达到多少个格子?

数据范围:

进阶:空间复杂度 ,时间复杂度
示例1

输入

1,2,3

输出

3
示例2

输入

0,1,3

输出

1
示例3

输入

10,1,100

输出

29

说明

[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7],[0,8],[0,9],[0,10],[0,11],[0,12],[0,13],[0,14],[0,15],[0,16],[0,17],[0,18],[0,19],[0,20],[0,21],[0,22],[0,23],[0,24],[0,25],[0,26],[0,27],[0,28] 这29种,后面的[0,29],[0,30]以及[0,31]等等是无法到达的      
示例4

输入

5,10,10

输出

21
推荐
public class Solution {

	public int movingCount(int threshold, int rows, int cols) {
		int flag[][] = new int[rows][cols]; //记录是否已经走过
		return helper(0, 0, rows, cols, flag, threshold);
	}

	private int helper(int i, int j, int rows, int cols, int[][] flag, int threshold) {
		if (i < 0 || i >= rows || j < 0 || j >= cols || numSum(i) + numSum(j)  > threshold || flag[i][j] == 1) return 0;		
		flag[i][j] = 1;
		return helper(i - 1, j, rows, cols, flag, threshold)
            + helper(i + 1, j, rows, cols, flag, threshold)
			+ helper(i, j - 1, rows, cols, flag, threshold) 
            + helper(i, j + 1, rows, cols, flag, threshold) 
            + 1;
	}

	private int numSum(int i) {
		int sum = 0;
		do{
			sum += i%10;
		}while((i = i/10) > 0);
		return sum;
	}
}

编辑于 2021-07-06 10:49:06 回复(81)
递归啊。先把 行坐标和列坐标的数位之和大于 threshold 的格子 标出来。然后就模拟四个方向递归
import java.util.*;
public class Solution {
    public int movingCount(int threshold, int rows, int cols) {
        res=0;
        isused=new boolean[rows][cols];
        for (int i = 0; i < rows; i++) {
            int a=i/10+i%10;
            for (int j = 0; j < cols; j++) {
               if(a+j/10+j%10>threshold) isused[i][j]=true;
            }
        }
        digui(0,0,rows,cols);
        return res;
    }
    public static int res;
    public static  boolean[][] isused;
    public static void digui(int x,int y,int rows,int cols){
        if(x>=rows||x<0||y>=cols||y<0) return;
        if(isused[x][y]) return;
        res++;
        isused[x][y]=true;
        digui(x-1,y,rows,cols);
        digui(x+1,y,rows,cols);
        digui(x,y-1,rows,cols);
        digui(x,y+1,rows,cols);
    }
}


发表于 2023-09-15 17:01:55 回复(0)
import java.util.*;
public class Solution {
    public int sum = 0;
    public int movingCount(int threshold, int rows, int cols) {
        int[][] a = new int[rows][cols];
        search(threshold, rows, cols, 0, 0, a);
        return sum;
    }
    public void search(int threshold, int rows, int cols, int nowRow, int nowCol,
                       int [][]a) {
        if (nowRow >= rows || nowCol >= cols) {
            return;
        }
        //剪枝判断
        if (a[nowRow][nowCol] == 1) {
            return;
        }
        int rowTen = nowRow / 10;
        int rowSingle = nowRow - 10 * rowTen;
        int colTen = nowCol / 10;
        int colSingle = nowCol - 10 * colTen;
        int nowThreshold = rowTen + rowSingle + colTen + colSingle;
        if (nowThreshold > threshold) {
            return;
        }
        if (a[nowRow][nowCol] == 0) {
            sum = sum + 1;
        }
        a[nowRow][nowCol] = 1;
        search(threshold, rows, cols, nowRow + 1, nowCol, a);
        search(threshold, rows, cols, nowRow, nowCol + 1, a);
    }
}

发表于 2023-07-28 17:43:27 回复(0)
//一道很经典的递归 类似问题还有岛屿问题
public class Solution {
    public int count = 0;
    public int movingCount(int threshold, int rows, int cols) {
        int[][] nums = new int[rows][cols];
        //state作为状态数组看一下当前这个点有没有判断过
        boolean[][] state = new boolean[rows][cols];
        recursion(threshold,rows,cols,0,0,state);
        return count;
    }

    public void recursion(int threshold,int rows,int cols,int i,int j,boolean[][] state){
        //越界的话就返回
        if(i<0 || i>=rows){
            return;
        }
        if(j<0 || j>=cols){
            return;
        }
        //计算一下行数之和和列数之和 看看这个点是否满足要求,不满足就返回
        int sum = 0;
        int k = i;
        while(k/10!=0){
            sum += k%10;
            k = k/10;
        }
        sum += k;
        int l = j;
        while(l/10!=0){
            sum += l%10;
            l = l/10;
        }
        sum += l;
        if(sum>threshold){
            return;
        }
        //我们选的点必须是没被走过的点,因为如果这个点被走过了,再算一遍就会造成重复计算
        if(!state[i][j]){
            //这个点之前没走过,现在我们来走,并把这个点的状态置为true
            state[i][j] = true;
            //能走到这,说明前面的重重条件都满足了,这是我们要的点
            count++;
            //从这个点开始,上下左右每次可以走1步,递归
            recursion(threshold,rows,cols,i-1,j,state);
            recursion(threshold,rows,cols,i+1,j,state);
            recursion(threshold,rows,cols,i,j-1,state);
            recursion(threshold,rows,cols,i,j+1,state);
        }
    }
}

发表于 2022-10-17 15:10:23 回复(0)
不是很难呀。。。。
import java.util.*;
public class Solution {
    int res=0;
    int target;
    int[][] log;
    int n;
    int m;
    public int movingCount(int threshold, int rows, int cols) {
        target=threshold;
        n=rows;
        m=cols;
        log=new int[rows][cols];
        count(0,0);
        return res;
    }
    
    public void count(int i,int j){
        if(i<0||i>=n||j<0||j>=m){
            return;
        }
        if(log[i][j]==1){
            //访问过了
            return;
        }
        int sum=getNum(i)+getNum(j);
        if(sum<=target){
            //说明可以访问
            res++;
            log[i][j]=1;
            count(i+1,j);
            count(i,j+1);
            count(i-1,j);
            count(i,j-1);
        }
        
    }
    
    //计算位数和
    public int getNum(int val){
        int sum=0;
        while(val>0){
            sum+=val%10;
            val/=10;
        }
        
        return sum;
    }
}


发表于 2022-09-09 22:19:39 回复(0)
方法1:遍历数组

import java.util.*;
public class Solution {
    public int sum(int i,int j){
        int sum=0;
        while(i>0){
            sum+=i%10;
            i/=10;
        }
        while(j>0){
            sum+=j%10;
            j/=10;
        }
        return sum;
    }
    public int movingCount(int threshold, int rows, int cols) {
        //遍历整个数组
        if(threshold==0)
            return 1;
        boolean flag[][]=new boolean[rows][cols];
        int sum=1;
        
    flag[0][0]=true;
        for(int i=0;i<rows;i++){
            for(int j=0;j<cols;j++){
                if(i==0&&j==0||sum(i,j)>threshold){
                    continue;
                } 
                //机器人从左边过来
               if(j-1>=0&&flag[i][j-1]){
                   sum+=1;
                   flag[i][j]=true;
               }
                //机器人从右边过来
              else  if(j+1<cols&&flag[i][j+1]){
                      sum+=1;
                   flag[i][j]=true;
                }
                //机器人从上边下来
           else   if(i-1>=0&&flag[i-1][j]){
               sum+=1;
        flag[i][j]=true;
           }else if(i+1<rows&&flag[i+1][j]){
                    sum+=1;
        flag[i][j]=true;
           }
                    
            }
        }
        return sum;
    }
}

方法2:回溯 深度遍历

import java.util.*;
public class Solution {
      public int sum(int i,int j){
        int sum=0;
        while(i>0){
            sum+=i%10;
            i/=10;
        }
        while(j>0){
            sum+=j%10;
            j/=10;
        }
        return sum;
    }
    public int movingCount(int threshold, int rows, int cols) {
        if(threshold==0)
            return 1;
        boolean [][]flag=new boolean[rows][cols];
     return   dfs(threshold,flag,0,0,rows,cols);
    }
    public int dfs(int threshold,boolean[][]flag,int i,int j, int rows, int cols){
        if(i<0||j<0||i>=rows||j>=cols){//数组越界
            return  0;
        }
        int count=0;
        if(!flag[i][j]&&sum(i,j)<=threshold){
            //如果当前位置 可以到达 从这个位置四散 找 上 下 左 右 中可以走的位置
            flag[i][j]=true; 
            count++;
            return count+ dfs(threshold,flag,i-1,j,rows,cols)+
                    dfs(threshold,flag,i+1,j,rows,cols)+
                    dfs(threshold,flag,i,j+1,rows,cols)+
                    dfs(threshold,flag,i,j-1,rows,cols);
        }
        //当前位置并不能到达 回溯 之前走过的路径不需要抹去
            return count;
    }
}

方法3:广度优先遍历



import java.util.*;
public class Solution {
      public int movingCount(int threshold, int rows, int cols) {
        if (threshold == 0)
            return 1;
//广度优先遍历
        boolean flag[][] = new boolean[rows][cols];
        ArrayList<Integer> list = new ArrayList<>();
        list.add(0);
        list.add(0);
        int count = 0;
        Queue<ArrayList<Integer>> queue = new LinkedList<>();
          queue.add(list);
        //对列中存放 机器人可以往下走的格子
        while (!queue.isEmpty()) {
            //1、取出队列的坐标
            list = queue.poll();
            int i = list.remove(0);
            int j = list.remove(0);
            if (i < 0 || j < 0 || i >= rows || j >= cols || sum(i, j) > threshold)//越界 或者不满足条件
                continue;
            if (!flag[i][j]) {//如果这个结点没有走过
                count++;
                flag[i][j] = true;
//如果(i,j)是满足要求的,那么机器人就可以继续走
                
                //向上走
                list = new ArrayList<>();
                list.add(i - 1);
                list.add(j);
                queue.add(list);
                //向下走
                list = new ArrayList<>();
                list.add(i + 1);
                list.add(j);
                queue.add(list);
                //向左
                list = new ArrayList<>();
                list.add(i);
                list.add(j - 1);
                queue.add(list);
                //向右
                list = new ArrayList<>();
                list.add(i);
                list.add(j + 1);
                queue.add(list);
            }
        }
    
        return count;
    

}

    public int sum(int i, int j) {
        int sum = 0;
        while (i > 0) {
            sum += i % 10;
            i /= 10;
        }
        while (j > 0) {
            sum += j % 10;
            j /= 10;
        }
        return sum;
    }
}

发表于 2022-08-31 18:16:23 回复(0)
我有点疑惑10,1,100这个用例,为什么[0][30]不算呢,0+3+0<10,不是吗,为什么排除这个哇,求大佬jiehuo
发表于 2022-08-25 21:06:41 回复(0)
import java.util.*;
public class Solution {
    int rows, cols, threshold;
    boolean[][] visited;
    public int movingCount(int threshold, int rows, int cols) {
        this.rows = rows;
        this.cols = cols;
        this.threshold = threshold;
        visited = new boolean[rows][cols];
        return dfs(0, 0, 0, 0);
    }
    int dfs(int x, int y, int sx, int sy) {
        if(x>=rows || y>=cols || threshold<sx+sy || visited[x][y]) return 0;
        visited[x][y]=true;
        return 1+dfs(x+1,y,(x+1)%10!=0?sx+1:sx-8, sy)+dfs(x,y+1,sx,(y+1)%10!=0?sy+1:sy-8);
    }
}
发表于 2022-08-11 09:48:43 回复(0)
简单dfs不需要回溯,只需要dfs得到最后可以访问节点的个数即可

import java.util.*;
public class Solution {
    public int movingCount(int threshold, int rows, int cols) {
        //简单的dfs,不存在回溯问题
        int[][] v = new int[rows][cols];
        return helper(0, 0, v, rows, cols, threshold);
    }
    
    public int helper(int i, int j, int[][] v, int rows, int cols, int t){
        //如果i,j超界,v[][]被访问过,或者不满足阈值要求,返回0种方法
        if(i<0||i>=rows||j<0||j>=cols||v[i][j]==1||getSum(i)+getSum(j)>t) return 0;
        v[i][j] = 1;
        //不是回溯,所以只需要往右和往下走。(剩下两个写上去也没问题)
        return helper(i+1,j,v,rows,cols,t) + helper(i,j+1,v,rows,cols,t) + 1;
    }
    
    public int getSum(int i){
        int res = 0;
        while(i > 0){
            res += i % 10;
            i /= 10;
        }
        return res;
    }
}


发表于 2022-07-05 20:06:42 回复(0)
    public int movingCount(int threshold, int rows, int cols) {
        // 初始化一个方格
        int[][] rect = new int[rows][cols];
        // 从0 0 开始运动
        backTrack(threshold, rect, 0, 0);
        return res;
    }

    // 记录可以到达的方格数目
    int res = 0;
    void backTrack(int threshold, int[][] rect, int i, int j){
        // 计算出i,j各位之和
        int num = i%10 + i/10%10 + i/100 + j%10 + j/10%10 +j/100;
        // 如果越界 ,i,j各位之和大于threshold, rect[i][j] = 1 (回头走) , rect[i][j] = 2 (第二次到达这个格子 因为已经递归过了所以不需要再递归了属于剪枝的操作) 直接return
        if( !(i >= 0 && i < rect.length) || !(j >= 0 && j < rect[0].length) || threshold < num || rect[i][j] == 1 || rect[i][j] == 2) return;
        // 走过的格子标记为1
        rect[i][j] = 1;
        // 总数加一
        res ++;
        // 上下左右
        backTrack(threshold, rect, i - 1, j);
        backTrack(threshold, rect, i + 1, j);
        backTrack(threshold, rect, i , j - 1);
        backTrack(threshold, rect, i , j + 1);
        // 回溯
        rect[i][j] = 2;
    }

发表于 2022-05-04 20:51:32 回复(0)
import java.util.*;
public class Solution {
    int count = 0;
    public int movingCount(int threshold, int rows, int cols) {
        boolean[][] visited = new boolean[rows][cols];
//         dfs(threshold, rows, cols, 0, 0, visited);
        Queue<int[]> q = new LinkedList<>();
        q.offer(new int[]{0, 0});
        while (!q.isEmpty()) {
            int[] tmp = q.poll();
            int m = tmp[0], n = tmp[1];
            if (m >= rows || n >= cols || visited[m][n] || sum(m) + sum(n) > threshold) continue;
            visited[m][n] = true;
            count++;
            if (m + 1 < rows) q.offer(new int[]{m+1, n});
            if (n + 1< cols) q.offer(new int[]{m, n+1});
        }
        return count;
    }
    public void dfs (int threshold, int rows, int cols, int i, int j, boolean[][] visited) {
        if (i >= rows || j >= cols || visited[i][j] || sum(i) + sum(j) > threshold) return;
        visited[i][j] = true;
        count++;
        dfs(threshold, rows, cols, i+1, j, visited);
        dfs(threshold, rows, cols, i, j+1, visited);
    }

    public int sum(int i) {
        int sum = 0;
        while(i != 0) {
            sum += i % 10;
            i /= 10;
        }
        return sum;
    }
}

发表于 2022-03-16 14:16:19 回复(0)
public class Solution {
    private int result = 0;
    public int movingCount(int threshold, int rows, int cols) {
        int[][] set = new int[rows][cols];
        dfs(threshold,rows,cols,0,0,set);
        return result;
    }
    private void dfs(int threshold, int rows, int cols,
                            int i,int j, int[][] set){
        if(i<0 || i>=rows || j<0 || j>=cols 
           || !isValid(threshold,i,j) || set[i][j]==1){
            return;
        }
        set[i][j]=1;
        result++;
        dfs(threshold,rows,cols,i-1,j,set);
        dfs(threshold,rows,cols,i+1,j,set);
        dfs(threshold,rows,cols,i,j-1,set);
        dfs(threshold,rows,cols,i,j+1,set);
    }
    
    private boolean isValid(int threshold,int rows,int cols){
        int count = 0;
        while(rows>0){
            count += rows%10;
            rows /= 10;
        }
        while(cols>0){
            count += cols%10;
            cols /= 10;
        }
        return count <= threshold;
    }
}

发表于 2022-02-17 00:25:02 回复(0)
public class Solution {
    public int movingCount(int threshold, int rows, int cols) {
        boolean dfs[][]=new boolean[rows][cols];//默认全为false
        return arriveNum(threshold,rows,cols,0,0,dfs);
        
    }
    //x,y为当前所在位置
    //dfs数组用来记录走过的路径
    public int arriveNum(int threshold, int rows, int cols,int x,int y,boolean dfs[][]){
        //循环跳出条件
        if(x<0||y<0||x>=rows||y>=cols||dfs[x][y]==true||addResult(x,y)>threshold)return 0;    
        //当前点符合规定,则对他标记
        dfs[x][y]=true;
        return 1+arriveNum(threshold,rows,cols,x+1,y,dfs)+arriveNum(threshold,rows,cols,x-1,y,dfs)
            +arriveNum(threshold,rows,cols,x,y+1,dfs)+arriveNum(threshold,rows,cols,x,y-1,dfs);
    }
    
    public int addResult(int x,int y){    //计算行列数字和
        int result=0,i,j;
        while(x>0){
            result+=x%10;
            x/=10;
        }
        while(y>0){
            result+=y%10;
            y/=10;
        }
        return result;
    }
}

发表于 2022-02-11 11:06:27 回复(0)
dfs深度优先:
public class Solution {
    boolean matrix[][];
    int threshold;
    public int movingCount(int threshold, int rows, int cols) {
        matrix = new boolean[rows][cols];
        this.threshold = threshold;
        return dfs(0,0);
         
    }
    public int dfs(int row, int col){
        // 如果越界,返回0
        if(row>=matrix.length||col>=matrix[0].length)
            return 0;
        // 如果走过这个格子,返回0
        if(matrix[row][col]==true)
            return 0;
        // 如果不满足给定条件:row+col<=threshold,返回0
        if(sum(row)+sum(col)>threshold)
            return 0;
        // 标记本坐标为true
        matrix[row][col]=true;
        // 返回向四个方向递归的和
        return 1+dfs(row+1,col)+dfs(row,col+1);
    }
     
    public int sum(int num){
        int sum=0;
        while(num!=0){
            sum += num%10;
            num/=10;
        }
        return sum;
    }
}
bfs广度优先:
import java.util.*;
public class Solution {
    public int movingCount(int threshold, int rows, int cols) {
        // bfs广度优先遍历

        // 建立boolean数组和队列
        boolean matrix[][] = new boolean[rows][cols];
        Deque<Point> deque = new LinkedList<>();
        // 定义计数器
        int count = 0;
        // 原点入队
        deque.addLast(new Point(0,0));
        // while广度优先遍历
        while(!deque.isEmpty()){
            // 先出队
            Point cur = deque.removeFirst();
            // 虽然只有未被访问过的元素才会被入队,因为同一层的元素可能被重复添加,所以还是要判断一下是否刚刚被访问过
            if(matrix[cur.getRow()][cur.getCol()]==true)
                continue;
            // 对应位置标记为true,代表已访问过
            matrix[cur.getRow()][cur.getCol()]=true;
            // 只要访问到就是合法的
            count++;
            // 因为不涉及到回溯,只关注下方和右侧元素即可
            // 当满足(1)下个元素未越界(2)下个元素未被访问(3)下个元素满足threshold约束时,入队下个元素
            if(cur.getRow()+1<rows && matrix[cur.getRow()+1][cur.getCol()]==false && sum(cur.getRow()+1)+sum(cur.getCol())<=threshold){
                deque.addLast(new Point(cur.getRow()+1, cur.getCol()));
            }
            if(cur.getCol()+1<cols && matrix[cur.getRow()][cur.getCol()+1]==false && sum(cur.getRow())+sum(cur.getCol()+1)<=threshold){
                deque.addLast(new Point(cur.getRow(), cur.getCol()+1));
            }
        }
        return count;
    }
    
    public int sum(int num){
        int input = num;
        int sum=0;
        while(input!=0){
            sum += input%10;
            input/=10;
        }
        return sum;
    }
}

// 注意建立内部类时不能带public
class Point{
    
    private int row;
    private int col;
    
    Point(int row,int col){
        this.row=row;
        this.col=col;
    }
    
    public int getRow(){
        return this.row;
    }
    public int getCol(){
        return this.col;
    }
}


发表于 2022-01-13 10:58:31 回复(0)
import java.util.*;
public class Solution {
    public int movingCount(int threshold, int rows, int cols) {
        if (rows == 0 || cols == 0)
            return 0;
        HashSet<String> set = new HashSet<>();
        return getRes(threshold, rows, cols, 0, 0, set);
    }
    
    public int getRes (int threshold, int rows, int cols, int i, int j, HashSet<String> set) {
        //是否超过合理范围
        if (i >= rows || j >= cols)
            return 0;
        //是否已经被检测过
        if (set.contains(i + ", " + j))
            return 0;
        //已经检测过当前位置
        set.add(i + ", " + j);
        //获取数位之和
        int sum = 0;
        int tmpi = i;
        int tmpj = j;
        int tmp = 0;
        while (tmpi > 0) {
            tmp = tmpi % 10;
            sum += tmp;
            tmpi = tmpi / 10;
        }
        while (tmpj > 0) {
            tmp = tmpj % 10;
            sum += tmp;
            tmpj = tmpj / 10;
        }
        if (sum > threshold)
            return 0;
        //符合条件,则算作一个有效位置,继续往下和右走
        //尽管机器人可以走左上右下,但因其起点为(0,0),
        //且右和下也都是来自左和上,说明之前的点已经走过了,
        //也就没必要再重复走了,所有只走右下即可
        return 1 + getRes(threshold, rows, cols, i+1, j, set) + 
            getRes(threshold, rows, cols, i, j+1, set);
    }
}

发表于 2022-01-07 14:08:45 回复(0)
import java.util.*;

public class Solution {
    public int movingCount(int threshold, int rows, int cols) {
        int startR = 0;
        int startC = 0;
        Node begin = new Node(startR, startC);
        Set<Node> visited = new HashSet<>();
        movingCount0(begin, visited, rows, cols, threshold);
        return visited.size();
    }
    
     public void movingCount0(Node begin, Set<Node> visited, int rows, int cols, int threhold) {
        int r = begin.r;
        int c = begin.c;
        //已经访问过,或者是阻挡点就不访问了
        if(visited.contains(begin) || isBlock(rows, cols, r, c, threhold)){
            return;
        }
        visited.add(begin);

        //向上一位
        Node up = new Node(r - 1, c);
        movingCount0(up, visited, rows, cols, threhold);

        //向下一位
        Node down = new Node(r + 1, c);
        movingCount0(down, visited, rows, cols, threhold);

        //向左一位
        Node left = new Node(r, c - 1);
        movingCount0(left, visited, rows, cols, threhold);

        //向右一位
        Node right = new Node(r, c + 1);
        movingCount0(right, visited, rows, cols, threhold);
    }

    public boolean isBlock(int rows, int cols, int r, int c, int threhold) {
        //已经超出边界,肯定是阻挡点
        if (r < 0 || r >= rows || c < 0 || c >= cols) {
            return true;
        }
        if (calSum(r) + calSum(c) > threhold) {
            return true;
        }
        return false;
    }

    private static int calSum(int num) {
        int sum = 0;
        while (num > 0) {
            sum += num % 10;
            num = num / 10;
        }
        return sum;
    }

    class Node {
        int r;
        int c;

        public Node(int r, int c) {
            this.r = r;
            this.c = c;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Node node = (Node) o;
            return r == node.r &&
                    c == node.c;
        }

        @Override
        public int hashCode() {
            return Objects.hash(r, c);
        }
    }

}

发表于 2021-12-25 14:51:44 回复(0)
回,就嗯回
public class Solution {
    int m;
    int n;
    public int movingCount(int threshold, int rows, int cols) {
        m = rows;
        n = cols;
        boolean[][] can = new boolean[rows][cols];
        for(int i = 0; i < rows; i++)
            for(int j = 0; j < cols; j++)
                can[i][j] = (bit(i) + bit(j)) <= threshold;
        int ans = 0;
        boolean[][] visited = new boolean[rows][cols];
        dfs(can, visited, 0, 0);
        for(int i = 0; i < rows; i++)
            for(int j = 0; j < cols; j++)
                if(visited[i][j])
                    ans++;
        return ans;
    }
    
    public void dfs(boolean[][] can, boolean[][] visited, int i, int j){
        if(i < 0 || i >= m || j < 0 || j >= n)
            return;
        if(!can[i][j] || visited[i][j])
            return;
        visited[i][j] = true;
        dfs(can, visited, i + 1, j);
        dfs(can, visited, i - 1, j);
        dfs(can, visited, i, j + 1);
        dfs(can, visited, i, j - 1);
    }
    
    public int bit(int x){
        int ans = 0;
        while(x > 0){
            ans += x % 10;
            x = x / 10;
        }
        return ans;
    }
}

发表于 2021-12-04 10:34:46 回复(0)
 private int res = 0;
    private  boolean[][] flags  = null;
    public int movingCount(int threshold, int rows, int cols) {
        flags = new boolean[rows][cols];
        Queue<Integer> queueX = new LinkedList<>();
        Queue<Integer> queueY = new LinkedList<>();
        queueX.add(0);
        queueY.add(0);
        res++;
        flags[0][0]=true;
        while(!queueX.isEmpty()){
            int size = queueX.size();
            while(size>0){
                int x = queueX.poll();
                int y = queueY.poll();
                if(x+1<rows&&(!flags[x+1][y])&&!overThreshold(threshold,x+1,y)){
                    res++;
                    flags[x+1][y]=true;
                    queueX.add(x+1);
                    queueY.add(y);
                }
                if(y+1<cols&&(!flags[x][y+1])&&!overThreshold(threshold,x,y+1)){
                    res++;
                    flags[x][y+1]=true;
                    queueX.add(x);
                    queueY.add(y+1);
                }
                if(x-1>=0&&(!flags[x-1][y])&&!overThreshold(threshold,x-1,y)){
                    res++;
                    flags[x-1][y]=true;
                    queueX.add(x-1);
                    queueY.add(y);
                }
                if(y-1>=0&&(!flags[x][y-1])&&!overThreshold(threshold,x,y-1)){
                    res++;
                    flags[x][y-1]=true;
                    queueX.add(x);
                    queueY.add(y-1);
                }
                size--;

            }
        }
        return res;
    }
    
    public boolean overThreshold(int threshold,int x,int y){
        int tmp = 0;
        while(x>0){
            tmp+=x%10;
            x/=10;
        }
        while(y>0){
            tmp+=y%10;
            y/=10;
        }
        return tmp>threshold;
    }

发表于 2021-10-05 20:51:03 回复(0)

问题信息

难度:
131条回答 108263浏览

热门推荐

通过挑战的用户

查看代码