劍指Offer面試題67:機器人的運動範圍 Java實現

題目:機器人的運動範圍
          地上有一個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)。

算法源程序:
/**************************************************************      
* Copyright (c) 2016, 
* All rights reserved.                   
* 版 本 號:v1.0                   
* 題目描述:機器人的運動範圍
* 		       地上有一個m行n列的方格。一個機器人從座標(0,0)的格子開始移動,它每次可以向左,向右,向上,向下移動一格,
* 			但不能進入行座標和列座標的位數之和大於k的格子。例如:當k爲18時,機器人能夠進入方格(35,37),
* 			因爲3+5+3+7 = 18;但它不能進入方格(35,38),因爲3 + 5+3+8 = 19.請問該機器人最多能到達多少個格子?
* 輸入描述:請輸入限制條件k:
*			5
*			請輸入方格的行數m:
*			10
*			請輸入方格的列數n:
*			10
* 程序輸出: 矩陣能到達的方格數是:
*			21
* 問題分析: 
* 算法描述: 這個方格也可以看出一個m*n的矩陣。同樣在這個矩陣中,除邊界上的格子之外其他格子都有四個相鄰的格子。 
*		  機器人從座標(0,0)開始移動。當它準備進入座標爲(i,j)的格子時,通過檢查座標的數位和來判斷機器人是否能夠進入。
*			如果機器人能夠進入座標爲(i,j)的格子,我們接着再判斷它能否進入四個相鄰的格子(i,j-1)、(i-1,j),(i,j+1)和(i+1,j)。
* 完成日期:2016-10-23
***************************************************************/

package org.marsguo.offerproject67;

import java.util.Scanner;
	/*
	@param threshold  	約束值
	@param rows 		方格行數
	@param cols			方格列數
	@return				最多可走的方格數
			*/
class SolutionMethod1{
	public int movingCount(int threshold,int rows,int cols){
		boolean[] visted = new boolean[rows*cols];
		for(int i = 0; i < visted.length; i++)
			visted[i] = false;
		
		int count = movingCountCore(threshold,rows,cols,0,0,visted);
		return count;
	}
	
	/*
	遞歸回溯方法:
	@param threshold	約束值
	@param rows			方格行數
	@param cols			方格列數
	@param row			當前處理的行號
	@param col			當前處理的列號
	@param visted		訪問標記數組
	@return				最多可走的方格
	*/
	public int movingCountCore(int threshold,int rows,int cols,int row,int col,boolean[] visted){
		int count = 0;
		if(check(threshold,rows,cols,row,col,visted)){
			visted[row*cols + col] = true;
			
			count = 1 + movingCountCore(threshold,rows,cols,row - 1,col,visted) +
					movingCountCore(threshold,rows,cols,row,col - 1,visted) + 
					movingCountCore(threshold,rows,cols,row + 1,col,visted) +
					movingCountCore(threshold,rows,cols,row,col + 1,visted);
		}
		return count;
	}
	
	boolean check(int threshold,int rows,int cols,int row,int col,boolean[] visted){
		if(row >= 0 && row < rows && col >= 0 && col < cols
				&& (getDigitSum(row) + getDigitSum(col) <= threshold)
				&& !visted[row* cols + col])
			return true;
		return false;
	}
	
	/*
	一個數字的位數之和
	@param	number 數字
	@return 數字的位數之和
	*/
	public int getDigitSum(int number){
		int sum = 0;
		while(number > 0){
			sum += number%10;
			number /= 10;
		}
		return sum;
	}
}
public class MovingCount {
	public static void main(String[] args){
		Scanner scanner = new Scanner(System.in);
		System.out.println("請輸入限制條件k:");
		int k = scanner.nextInt();
		System.out.println("請輸入方格的行數m:");
		int m = scanner.nextInt();
		System.out.println("請輸入方格的列數n:");
		int n = scanner.nextInt();
		
		SolutionMethod1 solution1 = new SolutionMethod1();
		
		scanner.close();
		System.out.println("矩陣能到達的方格數是:");
		System.out.println(solution1.movingCount(k, m, n));
	}
}



程序運行結果


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章