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

代码:里面有具体分析

class Solution {
public:
    /*
    int count_sum(int n);
    int findGrid(int threshold, int rows, int cols, int row, int col, bool* visited);
    */
    //计算一个数各位数之和
    int count_sum(int n)
    {
        int count = 0;
        while (n > 0)
        {
            int temp = n % 10;
            count += temp;
            n = n / 10;
        }
        return count;
    }

    int movingCount(int threshold, int rows, int cols)
    {
        //若初始参数不满足,返回空
        if (threshold < 0 || rows <= 0 || cols <= 0)
            return NULL;
        //访问矩阵:以一维数组方式表示二维数组元素
        bool* visited = new bool[rows * cols];
        //初始化visited数组为false
        memset(visited, false, rows * cols);

        //指定返回值,从(0,0)处开始进入迭代
        int count=findGrid(threshold, rows, cols,0,0, visited);
        //销毁访问矩阵
        delete[] visited;
        return count;
    }

    /*主要遍历部分:指定计数变量count_grids记录遍历各个满足条件的格子数量,
    注意这一题与面试题12矩阵中的路径一题不同,此题不能直接遍历所有格子,因为机器人threshod限制,根本跳不上去
    所以不能设置一个记录步数,遍历完整个矩阵方程就结束的标志,而是前后左右一步步试探,若满足条件则计数变量加1,
    否则放弃此节点。遍历到最后不满足if条件就返回计数值。
    */
    int findGrid(int threshold, int rows, int cols, int row, int col,bool* visited)
    {
        //计数变量
        int count_grids = 0;
        /*
        若当前点(row,col)满足条件可以继续前后左右遍历;
        条件有:row,col处于正确范围;row,col各位数之和不大于threshold;(row,col)未被访问。
        */
        if (row >= 0 && row < rows && col >= 0 && col < cols
            && count_sum(row)+count_sum(col) <= threshold 
            && !visited[row * cols + col])
        {
            //访问[row,col]节点,达到要求的格子数量+1,访问标志置为true
            visited[row * cols + col] = true;
            count_grids++;
            //这里很重要!!!直接加上满足条件的当前格子的前后左右即可,与上题不同啊。
            count_grids=count_grids+
                findGrid(threshold, rows, cols, row, col - 1, visited) +
                findGrid(threshold, rows, cols, row, col + 1, visited)+
                findGrid(threshold, rows, cols, row - 1, col, visited)+
                findGrid(threshold, rows, cols, row + 1, col, visited);
        }
        return count_grids;
    }
};

更新,方式一样,讲解有差异

这次的主要差错是将moveSum这个返回变量,也是全局变量当成 Move的参数了,它是从头到尾计算的格子数量,不是每个格子的属性,所以注意!

//求出一个数的位数之和
int getDigitSum(int digit)
{
    if (digit < 0)
        return 0;
    if (digit >= 0 && digit <= 9)
        return digit;
    int sum = 0;
    while (digit > 0)
    {
        sum += (digit % 10);
        digit = digit / 10;
    }
    return sum;
}

int GetGrids(int m, int n, int k)
{
    if (m < 0 || n < 0 || k < 0)
        return 0;
    //访问矩阵
    vector<vector<bool> >visit(m, vector<bool>(n, false));
    int result = Move(m, n, k, 0, 0, visit);
    return result;
}
//从起点startX,start开始能够遍历的格子的总数
int Move(int m, int n, int k,int startX,int startY,vector<vector<bool> >&visit)
{
    //!!!!!!这是个总数,不能放入Move参数中作为每个遍历的起始点
    int moveSum = 0;
    int digitSum = getDigitSum(startX) + getDigitSum(startY);
    //cout << "startX=" << startX << "  " << "startY=" << startY << " " << "digitSum=" << digitSum << endl;
    if (!(startX >= 0 && startX < m && startY >= 0 && startY < n &&
        visit[startX][startY] == false && digitSum <= k))
        return 0;

    //若当前格子满足条件,则计数加1,并向下遍历    
    visit[startX][startY] = true;
    moveSum = 1 + Move(m, n, k, startX - 1, startY, visit) +
        Move(m, n, k, startX + 1, startY, visit) +
        Move(m, n, k, startX, startY - 1, visit) +
        Move(m, n, k, startX, startY + 1, visit);
    //cout << moveSum << endl;
    return moveSum;
}

int main()
{
    int m = 4, n = 4, k = 1;
    cout << GetGrids(m, n, k) << endl;
    return 0;
}