leetcode 机器人的运动范围

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

示例 1:

输入:m = 2, n = 3, k = 1
输出:3

示例 2:

输入:m = 3, n = 1, k = 0
输出:1

提示:
1 <= n,m <= 100
0 <= k <= 20

解题思路:
运用递归的方法,从第一个数开始,向下或向右运动,每计算一个数将其标记,在之后的递归中不会用到。
递归的三个步骤:

  • 终止条件

  • 每一层的返回值

  • 每一层需要做什么

    在本题中,终止条件就是当遍历出界或者纵横左边位数之和大于k或者无法向四周遍历时,即可停止,故停止条件可以写为:

row >= m || col >= n || sum(row) + sum(col) > k || visited[row][col] == 1;

每层的返回值:返回方块个数,遇到停止条件时,返回0。每一层递归都返回符合要求的方块数。

每一层需要做什么:首先判断当前位置是否是终止位置,若不是,将当前visited置一,表示已经计算过当前方块,接着向下方或者向右方计算方块。

代码实现

int sum(int x){             //写一个求位数和的函数
    int s = 0;
    while (x != 0){
        s += x % 10;
        x = x / 10; 
    }
    return s;
}
//从0,0开始移动,意味着只会像下或者向右移动,也就是说只要本方格的下面或者右边有符合的x+y<=k即可
int movingsort(int x, int y, int m, int n, int k, int** visit){
    //如果数组越界或者索引和大于k或者已经被遍历过,则返回0
    if (x >= m || y >= n || sum(x) + sum(y) > k || visit[x][y] == 1 ){
        return 0;
    }
    visit[x][y] = 1;    //若没有被遍历过,则将它标记
    //向下或向左递归
    return movingsort(x + 1, y, m, n, k, visit) + movingsort(x, y + 1, m, n, k, visit) + 1;

}

int movingCount(int m, int n, int k){
    int i;
    int** visit = (int**)malloc(sizeof(int*) * m);      //给标记数组申请内存
    for (i = 0; i < m; i++){
        visit[i] = (int*)calloc(n, sizeof(int));
    }
    int count = movingsort(0, 0, m, n, k, visit);
    return count;
}
/*
int sum(int x){
    int s = 0;
    while (x != 0){
        s += x % 10;
        x = x / 10; 
    }
    return s;
}

int movingCount(int m, int n, int k){
    int i, j, count = 0;
    int flag[m][n];
    for (i = 0; i < m; i++){
        for (j = 0; j < n; j++){;
            if (i == 0 && j == 0){      //第一个数一定存在,对第一个数进行处理
                count++;
                flag[i][j] = 1;
            }
            else if ((i > 0 && flag[i - 1][j] == 1 || j > 0 && flag[i][j - 1] == 1) && sum(i) + sum(j) <= k){
                count++;
                flag[i][j] = 1;
            }
            else {
                flag[i][j] = 0;
            }
        }
    }
    return count;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值