问题描述
在上一个问题的基础上,如果事先将棋盘中设置有的地方已经被占据,马跳的过程中可能被别脚,如果马能够跳完剩下的棋盘,则遍历输出路径,如果不能跳完,则打印“没有找到全遍历路径”
输入
输入的第一行包含一个正整数n(n< =100)。
第二行为一个小于n * n的整数m。
接下来m行都包含两个整数,每一行代表第i行,第j列的位置已经有棋子。
接下来一行包含两个数,代表起点。
输出
马的遍历路径或者“没有找到全遍历路径。
解法:回溯剪枝
思路
(1)思路同上一题目一样,区别在于判断下一个位置是否可行的条件需要改变
(2)此题需要增加是否被别脚的情况,如果被别脚,则往回跳,继续向其他方向试探
代码
import java.util.Scanner;
/**
* 象棋中马的轨迹(有别脚)
*
* @author Administrator
*
*/
public class HoursePlus {
/* 存储棋盘 */
static int[][] arr;
/* 棋盘的宽度 */
static int n;
/* 别脚的个数 */
static int m;
/* 马跳棋盘的8个方向 */
static int[][] dir = { { -1, -2 }, { -1, 2 }, { -2, 1 }, { -2, -1 },
{ 1, 2 }, { 1, -2 }, { 2, -1 }, { 2, 1 } };
public static void main(String[] args) {
@SuppressWarnings("resource")
Scanner scanner = new Scanner(System.in);
n = scanner.nextInt();
arr = new int[n][n];
m = scanner.nextInt();
for (int k = 0; k < m; k++) {
int i = scanner.nextInt();
int j = scanner.nextInt();
// 已经被占据的位置用-1表示
arr[i][j] = -1;
}
int startI = scanner.nextInt();
int startJ = scanner.nextInt();
// 马开始跳的起点
arr[startI][startJ] = 1;
findPath(startI, startJ, 2);
System.out.println("没有找到全遍历路径");
}
/**
* 在棋盘中寻找马是否有可行路径,有则打出一个
*
* @param startI
* @param startJ
*/
private static void findPath(int startI, int startJ, int num) {
// 停止条件:已经遍历剩余的整个棋盘
if (num == n * n - m + 1) {
dispaly(arr);
System.exit(0);
} else {
for (int k = 0; k < 8; k++) {
int ii = startI + dir[k][0];
int jj = startJ + dir[k][1];
// 判断下一位置是否可行
if(judge(ii, jj, startI, startJ)){
// 走过这里标记
arr[ii][jj] = num;
findPath(ii, jj, num + 1);
// 走过,但是路径走不通,马跳回来,取消这里的标记
arr[ii][jj] = 0;
}
}
}
}
private static boolean judge(int ii, int jj, int i, int j) {
int b1 = ii - i > 0 ? 1 : -1;
int b2 = jj - j > 0 ? 1 : -1;
// 别脚的位置
i += b1;
j += b2;
// 判断别脚是否有棋子
if(i >= 0 && i < n && j >= 0 && j < n){
if(arr[i][j] == -1){
return false;
}
}
// 判断下一个位置是否已经被跳过
if(ii >= 0 && ii < n && jj >= 0 && jj < n){
if(arr[ii][jj] == 0){
return true;
}
}
return false;
}
/**
* 遍历输出
* @param arr
*/
private static void dispaly(int[][] arr) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.printf("%3d", arr[i][j]);
}
System.out.println();
}
System.out.println();
}
}