您的位置:首页 > Web前端

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

2018-01-24 17:41 323 查看
更多题目请点链接:《剑指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));

}


结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  机器人