剑指offer----013(机器人运动的范围)

更多题目请点链接:《剑指offer》目录索引


问题描述:

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

问题分析:

所走格子的范围条件:
1)必须在方格范围内
2)行坐标各位之和+列坐标各位之和 > = k

思路:

解决此问题可通过求解三个子问题来求解:
1)机器人遍历的格子范围:可通过回溯法进行>探测,如果坐标合法,则遍历其周围上下左右四个方向,周围合法的坐标即为可以走的格子
2)坐标是否满足条件:行坐标(或列坐标)可以是1位数,2位数,3位数…..,求坐标之和可将其拆分为:个位数+十位数+百位数+….
3)统计所走的格子数:机器人遍历合法坐标的格子数即为机器人到达的格子数

代码:

int GetDigitAdd(int x)
{
    //统计行(或者列)的坐标和
    int tmp=0;
    while(x!=0)
    {
        tmp+=x%10;
        x/=10;
    }
    return tmp;

}


int RootMoveCount(int rows,int cols,int k)
{
    //将走过的坐标保存在path中,统计走过的格子
    //动态开辟数组,和原来数组空间一样大
    int count=0;//记录走过的格子数
    int* path=(int*)malloc(sizeof(int)*rows*cols);
    if(path==NULL)
    {
        printf("申请空间失败\n");
    }
    int i=0;
    while(i<rows*cols)
    {
        path[i]=0;
        ++i;
    }
//统计所走格子数
count=RootMove(0,0,rows,cols,k,path);

    free(path);
    path=NULL;

    return count;
}
int RootMove(int row,int col,int rows,int cols,int k,int* path)
{
    if(row<0||row>=rows||col<0||col>=cols)
    {
        //访问越界
        return 0;
    }

    if((GetDigitAdd(row)+GetDigitAdd(col))<=k&&path[row*cols+col]==0)
    {
        //表示是合法坐标,将坐标保存在path中
        path[row*cols+col]=1;//进行标记
        //探测上下左右
        return 1+RootMove(row-1,col,rows,cols,k,path)
                +RootMove(row+1,col,rows,cols,k,path)
                +RootMove(row,col-1,rows,cols,k,path)
                +RootMove(row,col+1,rows,cols,k,path);
    }
    else
    {
        //坐标不合法,或者已经访问过,返回
        return 0;
    }
}



void Test()
{
    //多行多列
    printf("count:%d \n",RootMoveCount(5,6,21));
    //多行多列
    printf("count:%d\n",RootMoveCount(5,10,89));
    //只有一行
    printf("count:%d\n",RootMoveCount(1,10,21));
    //只有一列
    printf("count:%d\n",RootMoveCount(10,1,21));
    //只有一行一列
    printf("count:%d\n",RootMoveCount(1,1,15));
    //不合法坐标
    printf("count:%d\n",RootMoveCount(-1,1,12));

}

结果:

这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值