一、迷宫问题
package Recursion;
public class MiGong {
public static void main(String[] args) {
//先创建一个二维数组模拟迷宫
//地图
int[][] map = new int[8][7];
//使用1表示墙
//上下全部置为1
for (int i = 0; i < 7; i++) {
map[0][i] = 1;
map[7][i] = 1;}
//左右全部置为1
for (int j = 0; j < 8; j++) {
map[j][0] = 1;
map[j][6] = 1;
}
//设置挡板
map[3][1] = 1;
map[3][2] = 1;
// map[1][2] = 1;
// map[2][2] = 1;
//输出地图
for (int i = 0; i < 8; i++) {
for (int j = 0; j <7; j++) {
System.out.print(map[i][j]+" ");
}
System.out.println();
}
//使用递归回溯给小球找路
setWay(map, 1, 1);
//输出新的地图
System.out.println("新的地图");
for (int i = 0; i < 8; i++) {
for (int j = 0; j <7; j++) {
System.out.print(map[i][j]+" ");
}
System.out.println();
}
}
/**
* 如果小球能找到map[6][5]位置,说明找到通路
* 约定:当map[i][j]为0时表示改点没有走过,为1表示墙,为2表示通路可以走,为3表示改点已走过,但是走不通
* 策略:下右上左,如果改点走不通再回溯
* @param map 表示地图
* @param i
* @param j 小球初始位置
* @return 如果找到通路就返回true,否则返回false
*/
public static boolean setWay(int[][] map, int i, int j) {
if (map[6][5] == 2) {
return true; //通路已找到
}else {
if (map[i][j] == 0) {
map[i][j] = 2; //假定改点可以走通
if (setWay(map, i+1, j)) { //先向下走,如果可以走通返回true
return true;
}else if (setWay(map, i, j+1)) { //向右走
return true;
}else if (setWay(map, i-1, j)) { //向上走
return true;
}else if (setWay(map, i, j-1)) { //向左走
return true;
}else {
//说明改点走不通,是死路,回溯到上一点
map[i][j] = 3;
}
}else { //如果map[i][j]不等于0,可能是1,2,3,都走不通或者走过
return false;
}
}
return false;
}
}
二、八皇后问题
package Recursion;
public class Queue8 {
//定义一共有多少个皇后
static int max = 8;
//定义一个一维数组来存放各种解法
int[] solution = new int[max]; // solution = {1, 3, 4, 5, 7, 4, 3, 5} 第一个1代表第一个皇后在第一行第2列,第二个3代表第二个皇后在第二行第4列
//定义一共计算了多少次
static int JudgeCount = 0;
//定义一共有多少种解法
static int count = 0;
public static void main(String[] args) {
Queue8 queue8 = new Queue8();
queue8.set(0);
System.out.println(JudgeCount);
System.out.println(count);
}
//先编写一个方法判断第n个皇后是否会和前面的冲突
private boolean judge(int n) {
JudgeCount++;
for (int i = 0; i < n; i++) {
if (solution[n] == solution[i] || Math.abs(solution[n] - solution[i]) == Math.abs(n-i)) {
//如果传进来的第n个皇后和前面的第i个皇后在同一列或者同一行,则表示该方法不行
return false;
}
}
return true;
}
//编写一个方法放第n个皇后
//回溯的过程是从后往前的,比如第一种解法结束后,倒数第二个元素1开始进入set,前一种解法的最后一个元素3继续寻找位置
private void set(int n) {
if (n == max) {
//前面8个皇后都已放好,直接输出
print();
return;
}
//依次放入皇后并判断是否冲突
for (int i = 0; i < max; i++) {
//先把当前的这个皇后放到该行的第一列
solution[n] = i;
if (judge(n)) {
//如果不冲突就开始放第n+1个皇后,开始递归,如果冲突,就会放到该行的下一列位置
set(n+1);
}
}
}
//将各种解法输出
private void print() {
count++;
for (int i = 0; i < solution.length; i++) {
System.out.print(solution[i] + " ");
}
System.out.println();
}
}