问题描述
有一只地鼠不小心跑进了一个m*n的矩形田地里,假设地鼠在这块田地的初始位置为(x,y),并且每次只能向相邻的上下左右四个方向移动一步,那么在最多移动K次的情况下,有多少条路径可以逃出这片田地(一旦出去田地的边界就不能再往回走)?
输入描述:
输入数据包括五个参数:m,n,x,y,K
其中m和n的范围均为是[1,10],K的范围是[0,10]。
0<=x<m,0<=y<n。
输出描述:
输出成功逃跑的路径数量。
分析:一看题目就是需要采用穷举的方式(采用回溯的方式),一涉及的穷举,我首先想到的是采用递归的方式来进行求解。
本题有意思的是没有限制走过的路径不能重复,下面给出允许路径重复的解答和不允许路径重复的解答。对于允许重复,你就随便走,分上下左右四个方向遍历即可;而对于不允许重复的走法,需要对于走过的路径用一个数组记录下来。当找到对应的解或者移动的步骤已经达到K时,需要考虑回溯,既然回溯,就需要将当前走过的标识重新擦除,因为其他走法也可能走到此方格。
允许方格重复的走法:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int m = Integer.valueOf(br.readLine());
int n = Integer.valueOf(br.readLine());
int x = Integer.valueOf(br.readLine());
int y = Integer.valueOf(br.readLine());
int k = Integer.valueOf(br.readLine());
System.out.println(recursive(m, n, x, y, k));
}
public static int recursive(int m, int n, int x, int y, int remain) {
if(remain < 0) {
return 0;
}
if(x >= m || x < 0) {
return 1;
}
if(y >= n || y < 0) {
return 1;
}
return recursive(m, n, x + 1, y, remain - 1) +
recursive(m, n, x - 1, y, remain - 1) +
recursive(m, n, x, y + 1, remain - 1) +
recursive(m, n, x, y - 1, remain - 1);
}
}
路径上的方格不能重复的走法:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class SolutionTest {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int m = Integer.valueOf(br.readLine());
int n = Integer.valueOf(br.readLine());
int x = Integer.valueOf(br.readLine());
int y = Integer.valueOf(br.readLine());
int k = Integer.valueOf(br.readLine());
boolean[][] isWalk = new boolean[m][n];
isWalk[x][y] = true;
System.out.println(recursive(m, n, x, y, k, isWalk));
}
private static int recursive(int m, int n, int x, int y, int k, boolean[][] isWalk) {
if(k == 0) {
return 0;
}
int right = 0;
int top = 0;
int left = 0;
int bottom = 0;
if(y == n - 1) {
right = 1;
}else if(!isWalk[x][y + 1]) {
isWalk[x][y + 1] = true;
right = recursive(m, n, x, y + 1, k - 1, isWalk);
isWalk[x][y + 1] = false;
}
if(x == 0) {
top = 1;
}else if(!isWalk[x - 1][y]) {
isWalk[x - 1][y] = true;
top = recursive(m, n, x -1, y, k - 1, isWalk);
isWalk[x - 1][y] = false;
}
if(y == 0) {
left = 1;
}else if(!isWalk[x][y - 1]) {
isWalk[x][y -1] = true;
left = recursive(m, n, x, y - 1, k - 1, isWalk);
isWalk[x][y - 1]= false;
}
if(x == m - 1) {
bottom = 1;
}else if(!isWalk[x + 1][y]) {
isWalk[x + 1][y] = true;
bottom = recursive(m, n, x + 1, y, k -1, isWalk);
isWalk[x + 1][y] = false;
}
return right + top + left + bottom;
}
}