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

一、题目描述

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

二、解答

解题思路:这个方格也可以看出一个m*n的矩阵。同样在这个矩阵中,除边界上的格子之外其他格子都有四个相邻的格子。机器人从坐标(0,0)开始移动。当它准备进入坐标为(i,j)的格子时,通过检查坐标的数位和来判断机器人是否能够进入。如果机器人能够进入坐标为(i,j)的格子,我们接着再判断它能否进入四个相邻的格子(i,j-1)、(i-1,j),(i,j+1)和(i+1,j)。

本题可以利用回溯法来解决问题,回溯法基本概念与具体实现可以参见博文:https://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741376.html

代码实现如下:

 
	 
	 public static int movingCount(int thredshod, int rows, int cols) {
		 boolean[] visited = new boolean[rows*cols];
		 for(int i=0;i<visited.length;i++) {
				 visited[i]=false;
		 }
		 int count = moveCount(thredshod, rows,cols,0,0,visited);
		 return count;  
	 }
	 
	 //递归,回溯法
	 public static int moveCount(int thredshod, int rows, int cols,int row,int col, boolean[] visited) {
	 	 int count =0;
	 	 if(check(thredshod, rows, cols, row, col, visited)) {
	 		 count = 1 + moveCount(thredshod, rows, cols, row, col+1,visited) + 
	 				 moveCount(thredshod, rows, cols, row+1, col, visited) +
                     moveCount(thredshod, rows, cols, row, col-1, visited) + 
                     moveCount(thredshod, rows, cols, row-1, col, visited);
	 	 }	 
	 	 return count; 
	 }
	 
	 //检查当前位置是不是满足条件
	 public static boolean check(int thredshod, int rows,int cols,int row, int col, boolean[] visited) {
	 	 boolean flag = row>=0&&row<rows&&col>=0&&col<cols&&getDigitSum(row)+getDigitSum(col)<=thredshod&&!visited[row*cols+col];
	 	 //如果                                                                                                                                                                                                                                                                                                              
	 	 if(flag) {
	 		 visited[row*cols+col] = true;
	 		 return true;
	 	 }
	 	 return false;
	 }
	 
	 //求取一个数字所有位数之和
	 public static int getDigitSum(int number) {
	 	 int sum =0;
	 	 while(number>10) {
	 	 	 sum =number%10;
	 	 	 number = number/10;
	 	 }
	 	 sum +=number;
	 	 return sum;
	 }   

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值