首页 > 试题广场 >

机器人的运动范围

[编程题]机器人的运动范围
  • 热度指数:463185 时间限制: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)
//思路:dfs,搜索四个方向,vis记录该方格是否被搜索过,
// 预判方格是否合法,合法就从该方格接着搜索  
const int MAXN=100;
int dx[]={0,1,0,-1},dy[]={1,0,-1,0};    //四个方向	
int vis[MAXN][MAXN]={0};    //记录数组
int sum;    //记录结果

class Solution {
public:
    void dfs(int x,int y,int k,int m,int n)
    {
        vis[x][y]=1;
        for(int i=0;i<=3;++i)
        {
            int newx=x+dx[i],newy=y+dy[i];
            //预判方格是否合法,合法就从该方格接着搜索 
       if(vis[newx][newy]==0&&newx>=0&&newx<m&&newy>=0&&newy<n&&(newx%10+newx/10+newy%10+newy/10<=k))
            {
                ++sum;
                dfs(newx,newy,k,m,n);
            }
        }
    }
    int movingCount(int k, int rows, int cols)
    {
        if(k<0)
            return 0;
        memset(vis,0,sizeof(vis));
        sum=1;
        dfs(0,0,k,rows,cols);
        return sum;
        
    }
};

编辑于 2017-06-03 21:54:10 回复(5)
class Solution {
public:
    int movingCount(int threshold, int rows, int cols)
    {
        bool* flag=new bool[rows*cols];
        for(int i=0;i<rows*cols;i++)
            flag[i]=false;
        int count=moving(threshold,rows,cols,0,0,flag);//从(0,0)坐标开始访问;
        delete[] flag;
        return count;
    }
    //计算最大移动位置
    int moving(int threshold,int rows,int cols,int i,int j,bool* flag)
    {
        int count=0;
        if(check(threshold,rows,cols,i,j,flag))
        {
            flag[i*cols+j]=true;
            //标记访问过,这个标志flag不需要回溯,因为只要被访问过即可。
           //因为如果能访问,访问过会加1.不能访问,也会标记下访问过。
            count=1+moving(threshold,rows,cols,i-1,j,flag)
                   +moving(threshold,rows,cols,i,j-1,flag)
                   +moving(threshold,rows,cols,i+1,j,flag)
                   +moving(threshold,rows,cols,i,j+1,flag);
        }
        return count;
    }
    //检查当前位置是否可以访问
    bool check(int threshold,int rows,int cols,int i,int j,bool* flag)
    {
        if(i>=0 && i<rows && j>=0 && j<cols 
            && getSum(i)+getSum(j)<=threshold 
            && flag[i*cols+j]==false)
           return true;
        return false;
    }
    //计算位置的数值
    int getSum(int number)
    {
        int sum=0;
        while(number>0)
        {
            sum+=number%10;
            number/=10;
        }
        return sum;
    }
};

编辑于 2016-08-05 18:54:33 回复(10)
//java简单易懂版
public class Solution {
    int count=0;
    public int movingCount(int threshold, int rows, int cols)
    {
        boolean[] pass = new boolean[rows*cols];
        movingCount(threshold,0,0,rows,cols,pass);
        return count;
    }
    public void movingCount(int threshold, int i, int j,int rows, int cols,boolean[] pass){
        int index = i*cols+j;
        if(i<0||j<0||i>=rows||j>=cols||pass[index]==true)
            return ;
        if(helper(i,j)<=threshold){
            count++;
            pass[index]=true;
        }else{
            pass[index]=false;
            return;
        }
        movingCount(threshold, i-1, j,rows,  cols,pass);
        movingCount(threshold, i+1, j,rows,  cols,pass);
        movingCount(threshold, i, j-1,rows,  cols,pass);
        movingCount(threshold, i, j+1,rows,  cols,pass);
    }
    public int helper(int i,int j){
        int sum = 0;
        do{
            sum += i%10;
        }while((i = i/10) > 0);
        
        do{
            sum += j%10;
        }while((j = j/10) > 0);
        return sum;
    }
}

发表于 2019-07-22 04:37:50 回复(5)
DFS
class Solution {
    bool canreach(int threshold, int x, int y) {
        int sum = 0;
        while (x > 0) {
            sum += x % 10;
            x /= 10;
        }
        while (y > 0) {
            sum += y % 10;
            y /= 10;
        }
        return sum <= threshold;
    }
public:
    int movingCount(int threshold, int rows, int cols)
    {
        vector<vector<bool>> grid(rows);
        for (auto& row : grid) {
            row.resize(cols, false);
        }
        queue<pair<int, int>> que;
        if (canreach(threshold, 0, 0)) {
            que.push(make_pair(0, 0));
            grid[0][0] = true;
        }
        int cnt = 0;
        while (!que.empty()) {
            ++cnt;
            int x, y;
            tie(x, y) = que.front();
            que.pop();
            if (x + 1 < rows && !grid[x + 1][y] && canreach(threshold, x + 1, y)) {
                grid[x + 1][y] = true;
                que.push(make_pair(x + 1, y));
            }
            if (y + 1 < cols && !grid[x][y + 1] && canreach(threshold, x, y + 1)) {
                grid[x][y + 1] = true;
                que.push(make_pair(x, y + 1));
            }
        }
        return cnt;
    }
};

编辑于 2015-05-06 00:01:57 回复(5)

这道是典型的DFS || BFS 题

public class Solution {

    /**算法本质:
    * DFS||BFS 寻找连通分量
    * 
     * 题目分析:
     * 机器人在一个矩阵上的m*n个格子上移动,可进入的格子的集合可抽象为以下点集:
     * { (row, col) | (i%10+i/10+j%10+j/10) <= threshold }。且路径节点可重复,无步数限制。
     * 问:机器人能到达多少个格子?
     * 
     * 题目抽象:
     * 倘若我们把矩阵的每一个“格子”抽象成一个“结点”,把“格子相邻”抽象为“结点连通”(结点之间存在无向边),
     * 把“无法进入的格子”抽象成“与所有普通结点都不连通(不存在无向边)的孤点”,则整个问题可以抽象为:
     * 从某个结点出发,寻找无向图的连通分量的节点个数。很显然,可以使用DFS或者BFS进行实现
     * 
     * 算法实现:
     * 这里选择DFS进行实现。
     * 设置两个辅助boolean矩阵:visited与isWall。前者是DFS中的典型辅助矩阵,记录每个节点是否已访问过。
     * 后者用来表示每个节点是否是不能进入的“孤点”。
     * 设置静态变量nodeCnt,用于在DFS的过程中记录访问过的结点数
     * DFS递归函数的出口条件设置为:   
     * (outOfBoundary(rows, cols, row, col) || visited[row][col] || isWall[row][col] )
     * 即:“若超过边界(到矩阵之外)”或“访问过”或“是无法进入的结点” 则 return
     * 然后进行DFS。
     * */

    int nodeCnt = 0;
    boolean[][] visited;
    boolean[][] isWall;
    int threshold;
    int rows;
    int cols;

    public int movingCount(int threshold, int rows, int cols){
        if (threshold<0 || rows<=0 || cols<=0) //robust
            return 0;//牛客示例是0

        //init
        this.nodeCnt = 0;
        this.threshold = threshold;
        this.rows = rows;
        this.cols = cols;
        this.visited = new boolean[rows][cols];
        this.isWall = new boolean[rows][cols];
        for (int i=0;i<rows;i++){
            for (int j=0;j<cols;j++){
                this.visited[i][j]=false;
                if ( (i%10+i/10+j%10+j/10) > threshold )
                    this.isWall[i][j]=true;
                else
                    this.isWall[i][j]=false;
            }
        }

        //body
        DFS(0,0);
        return this.nodeCnt;
    }

    public void DFS(int row, int col){
        if (   outOfBoundary(rows, cols, row, col) 
            || visited[row][col] 
            || isWall[row][col] )
            return;

        //visit
        visited[row][col]=true;
        nodeCnt++;

        //DFS
        DFS(row+1, col);
        DFS(row-1, col);
        DFS(row, col+1);
        DFS(row, col-1);
    }

    public boolean outOfBoundary(int rows, int cols, int row, int col){
        return ( row<0 || row>=rows || col<0 || col>=cols );
    }

}
编辑于 2018-10-25 18:49:28 回复(3)
【java】和上一题类似,本题依然用DFS来解题,依然提供递归和非递归两种方法,了解一下!
方法一:非递归
思路:不带记忆的DFS搜索 + 限定条件 = 普通的DSF例题
1.需要记录已经遍历过的节点,用辅助矩阵visited[rows * cols]
2.每次加入时,count++标记已经遍历,这样下一个节点就不会遍历了
入栈条件
1.每一位的和小于等于threshold
2.x和 y  的边界条件
3.没有遍历过
 public int movingCount(int threshold, int rows, int cols)
    {
       if(rows <= 0 || cols <= 0 || threshold < 0) return 0;
        Stack<Integer> s = new Stack<>();
        boolean[] visited = new boolean[rows * cols];
        int[][] xoy = {{0,1,0,-1},{1,0,-1,0}};
        int count = 0;
        s.add(0);
        visited[0] = true;
        while(!s.empty()) {
            int  cur = s.pop();
            count++;
            for (int i = 0; i < 4; i++) {
                int x = cur % cols + xoy[0][i];
                int y = cur / cols + xoy[1][i];
                int sum = getDigitSum(x) + getDigitSum(y);
                if(x >= 0 && x < cols && y >= 0 && y < rows 
                        && sum <= threshold && !visited[x + y * cols]) {
                    s.add(x + y * cols);
                    visited[x + y * cols] = true;
                }
            }
        }
        return count;
    }

    private int getDigitSum(int i) {//获取位的和
        int sum = 0;
        while(i > 0) {
            sum += i % 10;
            i /= 10;
        }
        return sum;
    }
方法二:递归
* 递归的方式更加简单了,比上一题简单
* 出口:
*    0:不满足边界条件 ;已经遍历过;位数和大于阈值
* 1.递:
*     1.1标记遍历
*     1.2上下左右递归
* 2.归:返回count
 public int movingCount(int threshold, int rows, int cols)
    {
        if(rows <= 0 || cols <= 0 || threshold < 0) return 0;
        boolean[] visited = new boolean[rows * cols];
        return dfs(threshold,rows,cols,visited,0,0);
    }
 private  int dfs(int threshold, int rows, int cols, boolean[] visited, int x, int y) {
        if(x < 0 || x >= cols || y < 0 || y >= rows 
                || getDigitSum(x) + getDigitSum(y) > threshold || visited[x + y * cols])
            return 0;//出口
        visited[x + y * cols] = true;//标记
        return 1 + dfs(threshold, rows, cols, visited, x, y - 1)//归
                 + dfs(threshold, rows, cols, visited, x + 1, y)
                 + dfs(threshold, rows, cols, visited, x, y + 1)
                 + dfs(threshold, rows, cols, visited, x - 1, y);
    }
private int getDigitSum(int i) {
        int sum = 0;
        while(i > 0) {
            sum += i % 10;
            i /= 10;
        }
        return sum;
    }



编辑于 2018-06-15 21:36:10 回复(4)

python solution:

class Solution:
    def movingCount(self, threshold, rows, cols):
        self.row, self.col = rows, cols
        self.dict = set()
        self.search(threshold, 0, 0)
        return len(self.dict)

    def judge(self, threshold, i, j):
        return sum(map(int, list(str(i)))) + sum(map(int, list(str(j)))) <= threshold

    def search(self, threshold, i, j):
        if not self.judge(threshold, i, j) or (i, j) in self.dict:
            return
        self.dict.add((i, j))
        if i != self.row - 1:
            self.search(threshold, i + 1, j)
        if j != self.col - 1:
            self.search(threshold, i, j + 1)

要注意去重:(i,j) in self.dict

如果不加这一句,时间复杂度不会满足。

编辑于 2017-10-31 23:19:29 回复(8)
public class Solution {
 
    public int movingCount(int threshold, int rows, int cols) {
       int[][] flag = new int[rows][cols];
       return moving(threshold, rows, cols, flag, 0, 0);
    }
    
    public int moving(int threshold, int rows, int cols, int[][] flag, int i, int j){
        if(threshold <= 0 || i >= rows || i< 0 || j >= cols || j < 0 || (flag[i][j] == 1) || (sum(i) + sum(j) > threshold)){
            return 0;
        }
        flag[i][j] = 1;
        return moving(threshold, rows, cols, flag, i - 1, j)
            +moving(threshold, rows, cols, flag, i + 1, j)
            +moving(threshold, rows, cols, flag, i, j - 1)
            +moving(threshold, rows, cols, flag, i, j + 1)
            + 1;    
    }
    
    public int sum(int i ){
        if(i == 0){return i ;}
        int sum = 0;
        while(i != 0){
            sum += i % 10;
            i /= 10;
        }
        return sum;
    }

}

发表于 2015-10-19 08:43:43 回复(3)

利用队列宽度优先搜索
代码有点长但是很清晰

class Solution {
public:

    bool if_ok(int x, int y, int th){
        int sum = 0;
        string sx = to_string(x);
        string sy = to_string(y);
        for(int i = 0; i < sx.length();i++) sum += sx[i]-'0';
        for(int i = 0; i < sy.length();i++) sum += sy[i]-'0';
        return sum <= th;
    }


    int movingCount(int threshold, int rows, int cols){
        if(threshold <= 0) return 0;
        int stepx[4] = {1, -1, 0, 0};
        int stepy[4] = {0, 0, 1, -1};
        vector<vector<int> > dp(rows, vector<int>(cols, 0));
        queue<int> qx; queue<int> qy;
        qx.push(0); qy.push(0); dp[0][0] = 1;
        int ans = 0;
        while(!qx.empty()){
            ans++;
            int x = qx.front(); qx.pop();
            int y = qy.front(); qy.pop();
            for(int i = 0; i < 4; i++){
                if(x+stepx[i]<rows && x+stepx[i]>=0 &&
                   y+stepy[i]<cols && y+stepy[i]>=0 &&
                   if_ok(x+stepx[i],y+stepy[i],threshold) &&
                   dp[x+stepx[i]][y+stepy[i]] == 0){
                        qx.push(x+stepx[i]);
                        qy.push(y+stepy[i]);
                        dp[x+stepx[i]][y+stepy[i]] = 1;
                }
            }
        }
        return ans;
    }
};
发表于 2018-12-30 18:19:28 回复(1)

python solution:

class Solution:
    def getDigitSum(self,number):
        return sum(map(int,list(str(number))))
    def check(self,threshold,rows,cols,row,col,visited):
        if row>=0 and row<rows and col>=0 and col<cols and self.getDigitSum(row)+self.getDigitSum(col)<=threshold and not (row,col) in visited:
            return True
        return False
    def movingCountCore(self,threshold, rows, cols, row, col, visited):
        count=0
        if self.check(threshold,rows,cols,row,col,visited):
            visited.add((row,col))
            count=1+self.movingCountCore(threshold,rows,cols,row-1,col,visited)+self.movingCountCore(threshold,rows,cols,row,col-1,visited)+self.movingCountCore(threshold,rows,cols,row+1,col,visited)+self.movingCountCore(threshold,rows,cols,row,col+1,visited)
        return count
    def movingCount(self,threshold, rows, cols):
        # write code here
        if threshold<0 or rows<=0 or cols<=0:
            return 0
        visited=set()
        count=self.movingCountCore(threshold,rows,cols,0,0,visited)
        return count

发表于 2019-01-05 10:34:51 回复(0)
//非递归,利用栈实现
class Solution {
public:
    int Count(int row, int col){
        int count=0;
        while(row||col){
            count+=row%10+col%10;
            row/=10;
            col/=10;
        }
        return count;
    }
    int movingCount(int threshold, int rows, int cols){
        if((rows<1&&cols<1)||threshold<0)
            return 0;
        int R=1;
        bool* visited=new bool[rows*cols];
        memset(visited,0,rows*cols);
        visited[0]=true;
        stack<int> S;
        S.push(0);
        int p[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
        while(!S.empty()){
            int i=S.top()/cols,j=S.top()%cols;
            S.pop();
            for(int k=0;k<4;k++){
                int row=i+p[k][0],col=j+p[k][1];
                if(row>=0&&row<rows&&col>=0&&col<cols&&!visited[row*cols+col]&&Count(row,col)<=threshold){
                    S.push(row*cols+col);
                    visited[row*cols+col]=true;
                    R++;
				}
            }  
        }
        return R;
    }
};

发表于 2016-08-24 11:02:15 回复(2)
//回溯法。仔细审题。。。
class Solution {
public:
	int movingCount(int threshold, int rows, int cols) {
		int res = 0;
		bool* flag = new bool[rows*cols];
		memset(flag, 0, rows*cols);
		dfs(threshold, rows, cols, flag, 0, 0, res);
		return res;
	}
	void dfs(int threshold, int rows, int cols, bool* flag, int i, int j, int &res) {
		if (i<0 || i >= rows || j<0 || j >= cols)
			return;
		if (*(flag + i*cols + j) == 1)
			return;
		if (check(i,j,threshold)){
			res++;
			*(flag + i*cols + j) = 1;
			dfs(threshold, rows, cols, flag, i, j - 1, res);//左
			dfs(threshold, rows, cols, flag, i, j + 1, res);//右
			dfs(threshold, rows, cols, flag, i - 1, j, res);//上
			dfs(threshold, rows, cols, flag, i + 1, j, res);//下
		}
	}
    bool check(int ii,int jj,int threshold){
        int sum = 0;
        while (ii != 0) {
			sum += ii % 10;
			ii = ii / 10;
		}
		while (jj != 0) {
			sum += jj % 10;
			jj = jj / 10;
		}
        return sum<=threshold;
    }
};

发表于 2017-06-28 23:14:08 回复(3)
class Solution {
public:
  // BFS
  int movingCount(int threshold, int rows, int cols) {
    using P = pair<int, int>;
    vector<vector<int>> grid(rows, vector<int>(cols, 0));
    
    deque<P> q;
    q.emplace_back(0, 0);
    grid[0][0] = 1;
    
    const vector<int> dirs { 0, -1, 0, 1, 0 };
    
    int ans = 0;
    while (not q.empty()) {
      const auto [x, y] = q.front(); q.pop_front();
      ++ans;
      for (int i = 0; i < 4; ++i) {
        const int nx = x + dirs[i], ny = y + dirs[i + 1];
        if (not available(grid, rows, cols, nx, ny, threshold))
          continue;
        q.emplace_back(nx, ny);
        grid[ny][nx] = 1;
      }
    }
  
    return ans;
  }
  
  // DFS
  int movingCountII(int threshold, int rows, int cols) {
    vector<vector<int>> grid(rows, vector<int>(cols, 0));
    
    function<int(int, int)> dfs = [&](int x, int y) -> int {
      if (not available(grid, rows, cols, x, y, threshold))
        return 0;
      
      grid[y][x] = 1; // mark as seen
      
      int cnt = 1;
      cnt += dfs(x - 1, y);
      cnt += dfs(x + 1, y);
      cnt += dfs(x, y - 1);
      cnt += dfs(x, y + 1);
      return cnt;
    };
    
    return dfs(0, 0);
  }
  
private:
  bool available(vector<vector<int>>& grid, int rows, int cols, int x, int y, int threshold) {
    if (x < 0 || y < 0 || x == cols || y == rows || grid[y][x])
      return false;

    int s = 0;
    while (x) {
      s += x % 10;
      x /= 10;
    }
    while (y) {
      s += y % 10;
      y /= 10;
    }
    
    return s <= threshold;
  } 
};

发表于 2021-08-12 10:04:15 回复(0)
# -*- coding:utf-8 -*-
class Solution:
    def movingCount(self, threshold, rows, cols):
        # 计算每一位之和
        def getsum(num):
            sum = 0
            while num>0:
                sum += num%10
                num = num//10
            return sum
        path = []
        def back(start):
            if start in path or getsum(start[0]) + getsum(start[1])> threshold:
                return None
            if start[0]>=rows or start[1]>=cols:
                return None
            path.append(start)       # 从0,0开始向右向下遍历,减少走回头路的次数             
            back([start[0]+1,start[1]])
            back([start[0],start[1]+1])
        back([0,0])
        return len(path) 
           


编辑于 2020-03-09 12:45:41 回复(0)
class Solution {
public:
    int movingCount(int threshold, int rows, int cols)
    {
        vector<int> isVisit(rows*cols, 0);
        return helper(threshold, rows, cols, 0, 0, isVisit);
    }
private:
    int helper(int threshold, int rows, int cols, int row, int col, vector<int>& isVisit)
    {
        if (row < 0 || row >= rows || col < 0 || col >= cols ||digitnum(row) + digitnum(col) > threshold || isVisit[row*cols+col] == 1)
            return 0;
        isVisit[row*cols+col] = 1;
        return 1 + helper(threshold, rows,cols, row-1, col,isVisit) +
            helper(threshold, rows,cols, row+1, col,isVisit) +
            helper(threshold, rows,cols, row, col-1,isVisit) +
            helper(threshold, rows,cols, row, col+1,isVisit);
        
    }
    int digitnum(int num)
    {
        int cnt = 0;
        while(num)
        {
            cnt += num % 10;
            num /= 10;
        }
        return cnt;
    }
};

发表于 2019-02-27 21:25:01 回复(0)

思路

  • 这么多DFS的 我分享一个BFS的
  • 用队列记录每一个合法的点(BFS一般都用队列)
  • 建立二维数组标记走过的点,同时注意入队的时候就标记已经走过,否则下次还会入队
  • 注意threshold小于0的情况
import java.util.*;
class Point{
    int x;
    int y;
    public Point(int a,int b){
        x = a;
        y = b;
    }
}
public class Solution {
    public int movingCount(int threshold, int rows, int cols)
    {
        Point p = new Point(0,0);
        Deque<Point> de = new ArrayDeque<Point>();
        boolean[][] b = new boolean[rows][cols];
        de.addLast(p);
        int re= 0;
        if(threshold <0) return re;
        b[0][0] = true;
        while(!de.isEmpty()){
            Point t = de.poll();
            re++;
            if(t.x-1 >=0 && t.x-1 <rows && t.y >=0 && t.y<cols && getSum(t.x-1,t.y) <=threshold &&!b[t.x-1][t.y]) 
            {
                de.addLast(new Point(t.x-1,t.y));
                b[t.x-1][t.y] = true;
            }
            if(t.x+1 >=0 && t.x+1 <rows && t.y >=0 && t.y<cols && !b[t.x+1][t.y] && getSum(t.x+1,t.y) <=threshold) 
            {
                de.addLast(new Point(t.x+1,t.y));
                b[t.x+1][t.y] = true;
            }
            if(t.x >=0 && t.x <rows && t.y+1 >=0 && t.y+1<cols && !b[t.x][t.y+1] && getSum(t.x,t.y+1) <=threshold) 
            {
                de.addLast(new Point(t.x,t.y+1));
                b[t.x][t.y+1] = true;
            }
            if(t.x >=0 && t.x <rows && t.y-1 >=0 && t.y-1<cols &&  !b[t.x][t.y-1] && getSum(t.x,t.y-1) <=threshold) 
            {
                de.addLast(new Point(t.x,t.y-1));
                b[t.x][t.y-1] = true;
            }
        }
        return re;
    }
    private int getSum(int a,int b){
        int re = 0;
        while(a!=0) {
            re+=a%10;
            a = a/10;
        }
        while(b!=0){
            re+=b%10;
            b = b/10;
        }
        return re;
    }
}
发表于 2018-04-06 20:17:31 回复(1)
function movingCount(threshold, rows, cols)
{
    // write code here
    if(!threshold)return 1;
    if(!rows||!cols)return 0;
    var visited = [];
    var temp = [];
    var i, j;
    var count = {count:0};
    for (i = 0; i < rows; i++) {
      temp = [];
      for (j = 0; j < cols; j++) {
        temp.push(false);
      }
      visited.push(temp);
    }
    move(threshold, rows, cols, 0, 0, count, visited);
    return count.count;
}

function move(threshold, rows, cols, row, col, count, visited) {
    var isMove = false;
    if(rows>row&&cols>col&&col>=0&&row>=0&&!visited[row][col]) {
       if(bitSum(row) + bitSum(col) <= threshold) {
           visited[row][col] = true;
           count.count++;
           move(threshold, rows, cols, row+1, col, count, visited);
           move(threshold, rows, cols, row-1, col, count, visited);
           move(threshold, rows, cols, row, col-1, count, visited);
           move(threshold, rows, cols, row, col+1, count, visited);
       }
    }
    return isMove;
}

function bitSum(num) {
    var sum = 0;
    while(num) {
        sum+=num%10;
        num = parseInt(num/10)
    }
    return sum;
}

module.exports = {
    movingCount : movingCount
};

发表于 2017-08-29 12:41:03 回复(3)
public class Solution {
    int rows,cols,k,result;
    int movingCount(int threshold, int rows, int cols)
    {
        if(rows<=0||cols<=0||threshold<0) return 0;
        this.rows = rows;
        this.cols = cols;
        this.k    = threshold;
        boolean[][] visited = new boolean[rows][cols];
        help(0,0,visited);
        return result;
    }
    
    public void help(int i,int j, boolean[][] visited){
        if(i<0||i>=rows) return;//不符合要求的i和j直接返回
        if(j<0||j>=cols) return;
        if(visited[i][j]) return;//访问过该方格,直接返回
        visited[i][j] = true;//表明该方格已经访问过了
        int bitSum = 0;
        for(int temp=i,step=2;step-->0;temp=j){//判断位数和是否符合要求
            while(temp>0){
                bitSum += temp%10;
                temp /= 10;
            }
        }
        if(bitSum<=k){
            result++;
            help(i,j-1,visited);//往左
            help(i+1,j,visited);//往下
            help(i,j+1,visited);//往右
            help(i-1,j,visited);//往上
        }
    }
}

发表于 2015-06-23 00:08:08 回复(0)
class Solution {
private:
    int m_nRows;
    int m_nCols;
    int m_nThreshold;
public:
    int movingCount(int threshold, int rows, int cols)
    {
        int count = 0;
        bool * bVisited = new bool[rows*cols];
        memset(bVisited, false,rows*cols);
        m_nRows = rows;
        m_nCols = cols;
        m_nThreshold = threshold;
        movingCountHelper(bVisited,0,0,count);
        delete [] bVisited;
        return count;
    }

private:
    void movingCountHelper(bool * bVisited,int x,int y,int & count){
        if (x<0||x>=m_nRows||y<0||y>=m_nCols)
            return ;
        if (bVisited[getPosition(x,y)]){
            return ;
        }
        if (canBeVisited(x,y)){
            bVisited[getPosition(x,y)] = true;
            count++;
            movingCountHelper(bVisited,x-1,y,count);
            movingCountHelper(bVisited,x+1,y,count);
            movingCountHelper(bVisited,x,y-1,count);
            movingCountHelper(bVisited,x,y+1,count);
        }
    }
private :
    bool canBeVisited(int x,int y){
        int count = 0;
        while (x!=0){
            count+=(x%10);
            x/=10;
        }
        while (y!=0){
            count+=(y%10);
            y/=10;
        }
        return count<=m_nThreshold;
    }
    inline int getPosition(int x,int y){
        return  x*(m_nCols)+y;
    }

};


发表于 2017-04-12 10:44:30 回复(0)
分析:
用回溯法实现,从起点出发,从每个点的左右上下开始寻找,如果任何一个方向
已经寻找过或者超出边界或者不满足条件,则停止这个方向的寻找,从另外一个
方向开始寻找每次满足条件,则满足条件个数+1,这样一直找,直到没有满足条
件的点,用栈来存储满足条件的点
class Solution {
public:
    int movingCount(int threshold, int rows, int cols)
    {
  if(threshold<=0||rows<0||cols<0)
   return 0;
  int count=1;
  st1.push(0);
  st2.push(0);
  int x,y;
  bool *flag=new bool[rows*cols]();
  flag[0]=true;
  while(!st1.empty()&&!st2.empty())
  {
   x=st1.top();
   y=st2.top();
   if((x-1)>=0&&!flag[(x-1)*cols+y]&&checkMove(threshold,x-1,y))
   {
    count++;
    flag[(x-1)*cols+y]=true;
    st1.push(x-1);
    st2.push(y);
    continue;
   }
   if((x+1)<rows&&!flag[(x+1)*cols+y]&&checkMove(threshold,x+1,y))
   {
    count++;
    flag[(x+1)*cols+y]=true;
    st1.push(x+1);
    st2.push(y);
    continue;
   }
   if((y-1)>=0&&!flag[x*cols+y-1]&&checkMove(threshold,x,y-1))
   {
    count++;
    flag[x*cols+y-1]=true;
    st1.push(x);
    st2.push(y-1);
    continue;
   }
   if((y+1)<cols&&!flag[x*cols+y+1]&&checkMove(threshold,x,y+1))
   {
    count++;
    flag[x*cols+y+1]=true;
    st1.push(x);
    st2.push(y+1);
    continue;
   }
   st1.pop();
   st2.pop();
  }
  return count;
    }
 bool checkMove(int threshold,int rows,int cols)
 {
  int sum=0;
  while(rows!=0)
  {
   sum+=rows%10;
   rows/=10;
  }
  while(cols!=0)
  {
   sum+=cols%10;
   cols/=10;
  }
  if(sum>threshold)
   return false;
  else
   return true;
 }
 stack<int> st1,st2;
};

编辑于 2015-09-02 17:26:12 回复(1)