迷宫问题
核心思路在于递归线路选择
/**
* 约定迷宫的出口是row,column 即右下角的那个点
* 约定数字1为墙,2为走过的路,3为死路,0表示没有走过
*/
public class MazeDemo {
final int x;
final int y;
int[][] maze;
public MazeDemo(int x, int y) {
this.x = x;
this.y = y;
initMaze();
}
public void initMaze() {
int[][] maze = new int[x][y];
for (int i = 0; i < x; i++) {
maze[i][0] = 1;
maze[i][y - 1] = 1;
}
for (int i = 0; i < y; i++) {
maze[0][i] = 1;
maze[x - 1][i] = 1;
}
this.maze = maze;
}
public void print() {
for (int[] x : maze) {
for (int y : x) {
System.out.print(y + "\t");
}
System.out.println();
}
}
public void setBlock(final int row, final int column) {
maze[row][column] = 1;
}
/**
* 起点位置 左上方顶点 坐标
* 移动策略默认采用 ↓ → ↑ ←
*
* @param x
* @param y
*/
public boolean passMaze(final int x, final int y) {
if (maze[this.x - 2][this.y - 2] == 2) {
// 最后出口走到了退出
return true;
} else {
// 没走过
if (maze[x][y] == 0) {
maze[x][y] = 2;
if (passMaze(x + 1, y)) {
//向下走
return true;
} else if (passMaze(x, y + 1)) {
// 向右走
return true;
} else if (passMaze(x - 1, y)) {
// 向上走
return true;
} else if (passMaze(x, y - 1)) {
// 向左走
return true;
} else {
// 上下左右都走不通
maze[x][y] = 3;
return false;
}
}
return false;
}
}
public static void main(String[] args) {
MazeDemo mazeDemo = new MazeDemo(7, 8);
mazeDemo.setBlock(3, 1);
mazeDemo.setBlock(3, 2);
mazeDemo.print();
mazeDemo.passMaze(1, 1);
System.out.println("===============");
mazeDemo.print();
}
}
八皇后问题
核心算法在于如何判断是否在同一行的算法solution[i] == solution[n]
判断是否在同一斜线的算法 当前皇后和老皇后的行差值和当前皇后和老皇后的列差值是否相等
Math.abs(n-i)==Math.abs(solution[n]-solution[i])
// 用一个一维数组表示八皇后问题的一种解法 数组的index 为第index排的皇后 值为皇后在这排摆放的位置
// 如arr[0,5,7,3,4,5,6,7]为第1排皇后摆第一排第1列,第2个皇后摆在第2第5+1列,第3个皇后摆在第排7+1列...
public class Queen8 {
public final int max = 8;
static int count = 0;
// 一种解决方案
public int[] solution = new int[max];
public void print() {
System.out.println(Arrays.toString(solution));
}
/**
* 摆放棋子
* n表示摆放第几个皇后
*/
public void putQueen(int n) {
if (n == max) {
// 摆放最后一个皇后的下一个皇后了说明已经摆放完毕
count++;
print();
return;
}
// 从第n行第一列开始尝试摆放
for (int i = 0; i < max; i++) {
// 将当前这个第n个皇后 依次尝试摆放到0-8所有的位置
solution[n] = i;
// 摆好了之后 solution[n] = i 已经完成了复制 再调用check方法
if (check(n)) { // 如果不冲突的话 就继续放下一个即下一排皇后开始递归
putQueen(n + 1);
}
}
}
/**
* 检查第N行的皇后是否跟之前的皇后冲突
* false表示冲突 true表示不冲突
*
* @param n
* @return
*/
public boolean check(int n) {
// 判断之前摆放的棋子是否在同一行同一列
for (int i = 0; i < n; i++) {
// solution[i] == solution[n] 判断之前的所有棋子是否同一列
// solution[i]就表示第i个皇后的位置是solution[i] solution[n]表示当前这一行n的摆放的列位置 从第1行开始一直循环判断往上判断
// 如果发现有重复的说明之前有棋子摆放在了同一列 直接返回false
// Math.abs(n - i) == Math.abs(solution[n] - solution[i]
// 当前皇后和老皇后的差,如果等于 他们位置的差,就表明在同一斜线
// Math.abs(n-i) n 当前皇后 i之前摆好的皇后
// Math.abs(solution[n] - solution[i]) 当前皇后位置 - 老皇后的位置
if (solution[i] == solution[n] || Math.abs(n - i) == Math.abs(solution[n] - solution[i])) {
return false;
}
}
return true;
}
public static void main(String[] args) {
Queen8 queen8 = new Queen8();
// 从第一排开始
queen8.putQueen(0);
System.out.println(count);
}
}