/**************************************************************
* 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));
}
}
程序運行結果