第13题:机器人的运动范围

题目描述

地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?

 

考点:回溯法

1.从(0,0)开始走,每成功走一步标记当前位置为true,然后从当前位置往四个方向探索,

返回1 + 4 个方向的探索值之和。

2.探索时,判断当前节点是否可达的标准为:

1)当前节点在矩阵内;

2)当前节点未被访问过;

3)当前节点满足limit限制。

 

 思路


    //1.计数函数int,参数:阈值int,矩阵行数int,矩阵列数int,返回值:计数int    
        //1.1如果阈值为负,矩阵不存在,返回0        
        //1.2分配访问矩阵bool并初始化        
        //1.3初始化计数为0      
        //1.4 从(0,0)开始计数
        //1.5返回计数 
        
    //2.搜索函数int ,参数:阈值int,矩阵行数int,矩阵列数int,当前行数int,当前列数int,访问矩阵数组bool*,返回值:计数int
        //2.1 初始计数为0         
        //2.2 如果该位置满足条件 
            //2.2.1 更新访问矩阵            
            //2.2.2 从该位置的上下左右开始作为起点依次行递归调用,这里是计数,所以用+,如果是找存在路径就用或。 
        //2.3 返回计数 

    
    //3.匹配函数bool,参数::阈值int,矩阵行数int,矩阵列数int,当前行数int,当前列数int,访问矩阵数组bool*,返回值:是否满足条件 bool   
        //3.1 如果该位置满足条件:1.不越界。2.不超过阈值。3.未曾访问过。则返回真。
        //3.2 否则返回假。 
         
    //4. 计算数位之和函数int,参数:数字int,返回值:数位之和int。
         //4.1 初始化数为之和为0             
        //4.2 循环         
            //4.2.1 取余,先加个位数            
            //4.2.2 除以10,降一位 
        //4.3 返回sum 
    
     

class Solution {
public:
    //1.计数函数int,参数:阈值int,矩阵行数int,矩阵列数int,返回值:计数int
    int movingCount(int threshold, int rows, int cols)
    {
        //1.1如果阈值为负,矩阵不存在,返回0
        if(threshold<0||rows<0||cols<0)
            return 0;
        
        //1.2分配访问矩阵bool并初始化
        bool* visited=new bool[rows*cols];
        memset(visited,0,rows*cols);
        
        //1.3初始化计数为0
        int count=0;
        //1.4 从(0,0)开始计数
        count= movingCountCore(threshold,rows,cols,0,0,visited);
        
        
        //返回计数
        return count;
    }
    
    
    //2.搜索函数int ,参数:阈值int,矩阵行数int,矩阵列数int,当前行数int,当前列数int,访问矩阵数组bool*,返回值:计数int
    int movingCountCore(int threshold,int rows,int cols,int row,int col,bool* visited)
    {
        //2.1 初始计数为0
        int count=0;
        
        //2.2 如果该位置满足条件
        if(check(threshold,rows,cols,row,col,visited))
        {
            //2.2.1 更新访问矩阵
            visited[row*cols+col]=true;
            
            //2.2.2 从该位置的上下左右开始作为起点依次行递归调用,这里是计数,所以用+,如果是找存在路径就用或。
            count=1+ movingCountCore(threshold,rows,cols,row-1,col,visited)+//上
                movingCountCore(threshold,rows,cols,row+1,col,visited)+//下
                movingCountCore(threshold,rows,cols,row,col-1,visited)+//左
                movingCountCore(threshold,rows,cols,row,col+1,visited);//右
            
            
        } 
        //2.3 返回计数
        return count;
    }
    
    //3.匹配函数bool,参数::阈值int,矩阵行数int,矩阵列数int,当前行数int,当前列数int,访问矩阵数组bool*,返回值:是否满足条件 bool
    bool check(int threshold,int rows,int cols,int row,int col,bool* visited)
    {
        //3.1 如果该位置满足条件:1.不越界。2.不超过阈值。3.未曾访问过。则返回真。
        if(row<rows&&col<cols&&col>=0&&row>=0&&!visited[col+cols*row]&&getDigitSum(row)+getDigitSum(col)<=threshold)
            return true;
       //3.2 否则返回假。
        return false;
    }
    
    //4. 计算数位之和函数int,参数:数字int,返回值:数位之和int。
    int getDigitSum(int num)
    {
        //4.1 初始化数为之和为0
        int sum=0;
        
        //4.2 循环
        while(num>0)
        {
            //4.2.1 取余,先加个位数
            sum+=num%10;
            //4.2.2 除以10,降一位
            num/=10;
        }
        
        //4.3 返回sum
        return sum;
    }
    
    
};

 

posted @ 2019-02-01 14:12  lightmare  阅读(134)  评论(0编辑  收藏  举报