剑指Offer - 面试题13:机器人的运动范围

简介: 剑指Offer - 面试题13:机器人的运动范围

题目

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


分析

dfs + 回溯

我们可以设置一个二维数组用来区别该位置是否计算过。初始化成0,如果计算过就设置为-1。然后从(0,0)开始,如果(0,0)都不符合那就所有位置都不符合了。然后与依次向上、下、左、右遍历。如下k=5时


绿色表示机器人可以到达的位置,

蓝色表示机器人不可以到达的位置,但是坐标符合。

空白就是坐标不符合

分析上图,我们发现9到10,19到20是零界点。

再测试k=11

总结上图。我们可以发现从(0,0)开始向下和向右移动就可以到达所有绿色区域,

C

#include<stdio.h>
#include<stdlib.h>
int getDigitSum(int num);
int movingCount(int rows, int cols, int k);
int movingCountCore(int** test, int rows, int cols, int i, int j, int k);
int main()
{
  int k = 5;
  int ret = movingCount(80, 100, k);
  if (-1 == ret)
  {
    printf("行或列小于零\n");
  }
  else
  {
    printf("机器人能够到达%d个格子\n", ret);
  }
  return 0;
}
int movingCount(int rows, int cols, int k)
{
  if (rows <= 0 || cols <= 0)
  {
    return -1;
  }
  int** test = (int**)calloc(rows * cols, sizeof(int));//申请一个标志数组
  if (NULL == test)
  {
    perror("申请空间失败");
  }
  int count = movingCountCore(test, rows, cols, 0, 0, k);
  free(test);//释放test数组
  return count;
}
int movingCountCore(int** test, int rows, int cols, int i, int j, int k)
{
  //行列超出边界,或者test[i][j]的值已经被修改,或者行坐标和列坐标的数位之和大于k的格子
  if (i >= rows || j >= cols || *((int*)test + i * cols + j) != 0 || (getDigitSum(i) + getDigitSum(j)) > k)
  {
    return 0;
  }
  *((int*)test + i * cols + j) = -1;
  //依次向下、右遍历
  return 1+ movingCountCore(test, rows, cols, i + 1, j, k)
    + movingCountCore(test, rows, cols, i, j + 1, k);
}
int getDigitSum(int num)//坐标的位数之和
{
  int sum = 0;
  while (num != 0)
  {
    sum += num % 10;
    num /= 10;
  }
  return sum;
}


分析一下坐标的位数和:

当 0 <= i <= 9时,位数和就是本身

当 10 <= i <=19时,位数和是1+个位数

当 11 <= i <= 29时,位数和是2+个位数


位数和 = i %10 + 个位数

那么我们就可以省去getDigitSum()函数了。

优化后:

C

#include<stdio.h>
#include<stdlib.h>
int movingCount(int rows, int cols, int k);
int movingCountCore(int** test, int rows, int cols, int i, int j, int k);
int main()
{
  int k = 5;
  int ret = movingCount(80, 100, k);
  if (-1 == ret)
  {
    printf("行或列小于零\n");
  }
  else
  {
    printf("机器人能够到达%d个格子\n", ret);
  }
  return 0;
}
int movingCount(int rows, int cols, int k)
{
  if (rows <= 0 || cols <= 0)
  {
    return -1;
  }
  int** test = (int**)calloc(rows * cols, sizeof(int));//申请一个标志数组
  if (NULL == test)
  {
    perror("申请空间失败");
  }
  int count = movingCountCore(test, rows, cols, 0, 0, k);
  free(test);//释放test数组
  return count;
}
int movingCountCore(int** test, int rows, int cols, int i, int j, int k)
{
  //行列超出边界,或者test[i][j]的值已经被修改,或者行坐标和列坐标的数位之和大于k的格子
  if (i >= rows || j >= cols || *((int*)test + i * cols + j) != 0 || (i % 10 + i / 10 + j % 10 + j / 10) > k)
  {
    return 0;
  }
  *((int*)test + i * cols + j) = -1;
  //依次向下、右遍历
  return 1+ movingCountCore(test, rows, cols, i + 1, j, k)
    + movingCountCore(test, rows, cols, i, j + 1, k);
}


本章完!

目录
相关文章
|
3月前
|
人工智能 搜索推荐 机器人
挑战未来职场:亲手打造你的AI面试官——基于Agents的模拟面试机器人究竟有多智能?
【10月更文挑战第7天】基于Agent技术,本项目构建了一个AI模拟面试机器人,旨在帮助求职者提升面试表现。通过Python、LangChain和Hugging Face的transformers库,实现了自动提问、即时反馈等功能,提供灵活、个性化的模拟面试体验。相比传统方法,AI模拟面试机器人不受时间和地点限制,能够实时提供反馈,帮助求职者更好地准备面试。
142 2
|
5月前
|
数据可视化 机器人 Python
实例9:四足机器人运动学正解平面RR单腿可视化
本文是关于四足机器人正向运动学(FK)的实例教程,通过Python编程实现了简化的mini pupper平面二连杆模型的腿部可视化,并根据用户输入的关节角计算出每个关节相对于基坐标系的坐标。
98 1
|
5月前
|
机器人
PUN ☀️六、机器人基础设置:运动、相机、攻击与生命值
PUN ☀️六、机器人基础设置:运动、相机、攻击与生命值
|
5月前
|
数据可视化 算法 机器人
实例10:四足机器人运动学逆解可视化与实践
本文是关于四足机器人逆运动学(IK)的实例教程,介绍了逆运动学的概念、求解方法、多解情况和工作空间,并通过Python编程实现了简化的mini pupper平面二连杆模型的逆运动学可视化,包括单腿舵机的校准和动态可视化运动学计算结果。
294 0
|
5月前
|
安全 编译器 C++
【剑指offer】2.2编程语言(p22-p25)——面试题1:string赋值运算函数
【剑指offer】2.2编程语言(p22-p25)——面试题1:string赋值运算函数
|
8月前
【一刷《剑指Offer》】面试题 23:从上往下打印二叉树
【一刷《剑指Offer》】面试题 23:从上往下打印二叉树
|
8月前
【一刷《剑指Offer》】面试题 22:栈的压入、弹出系列
【一刷《剑指Offer》】面试题 22:栈的压入、弹出系列
|
8月前
|
算法
【一刷《剑指Offer》】面试题 21:包含 main 函数的栈
【一刷《剑指Offer》】面试题 21:包含 main 函数的栈
|
8月前
【一刷《剑指Offer》】面试题 20:顺时针打印矩阵
【一刷《剑指Offer》】面试题 20:顺时针打印矩阵
|
8月前
【一刷《剑指Offer》】面试题 19:二叉树的镜像
【一刷《剑指Offer》】面试题 19:二叉树的镜像

热门文章

最新文章