最近在学习递归方法,所以就接触到了很经典的八皇后问题。
递归就是方法自己调用自己,每次调用时传入不同的变量。
八皇后问题是是由国际象棋棋手马克斯·贝瑟尔于1848年提出的问题...等等,不懂可以去百度。
简单来说就是在一个8 *8规模的棋盘上,放置8个棋子,规定 每个棋子都不能和其他7个棋子 在同行 同列 或者同斜线。只要有一个棋子不符合规定都不能算成功解决把皇后问题。
然后就有人很无聊 想知道如果像上述规则那样摆 一共有多少种摆法?
如果只靠人去算的话,无疑是一种工作量庞大的活。而递归方法能有效的解决这类问题。
八皇后放置的策略:
1. 第一个皇后:先放到第一行第一列,判断是否符合八皇后的摆放规则(不同行 不同列 不同斜线),不符合就顺位放到第二列...,以此类推。
注:第一个皇后放在第一行第一列肯定是符合规则的。但是电脑不知道,所以编程中还是会判断
2. 第二个皇后:放在第二行第一列,判断是否符合规则,不符合继续放到第二列...,以此类推。
3. 第三个皇后:和上面的方法类似.......一直到第八个皇后也找到了正确的摆放位置,这样我们就算是找到了一个正确解(摆法)。
然后就会回溯,第一个皇后放到第一行第一列的所有正确解(摆法),全部得到
注:将第一个皇后的位置固定,其他皇后的位置只要按规则摆放就行,故有很多正确解
4. 然后继续将第一个皇后放到第二列,在循坏执行1,2,3,4的步骤。
注意:
这里用 一维数组 来表示棋盘, 例: arr[8] = {0,1,5,7,4,2,1,3} , 对应 arr 下标表示第几行,即第几个皇后;a[i]= row , 表示第i+1个皇后,放在第i+1行的第row+1列。
代码:
import java.util.Scanner;
public class eightQueens{
public static void main(String[] ards){
T t = new T();
int arr[] = new int[8];//使用一维数组保存 棋盘规模 8*8
t.putQueen(arr,0);
System.out.println("八皇后问题一共有" + t.count +"情况");
}
}
class T{
//验证功能:判断棋子放在第几行 是否符合八皇后的规则: 与其他棋子 不能同列 不能同行 不能同一斜线
//如果符合八皇后游戏规则 返回 true 否则 返回false 使用boolean返回类型
// arr 表示棋盘 n 表示放入棋子在第n+1行 arr[n] 表示放入棋子在第 arr[n] + 1列
public boolean verify(int arr[],int n){
for (int i = 0;i < n ;i++ ) {
if (arr[n] == arr[i] || Math.abs(n - i) == Math.abs(arr[n] - arr[i])) {
return false;
}
}
return true;
}
//八皇后棋子放置策略:
//用一维数组arr 表示棋盘 i 表示初始棋子放置棋盘第i+1行
//arr[i] 表示棋盘第arr[i]+1列
//设置递归的出口 当棋子放到第8行 验证成功时 即 verify(arr,7) 返回true
//打印八皇后放置棋子的8个位置
int count = 0;//全局变量
public void putQueen(int[] arr,int i){
if (verify(arr,7)) {
count++;
System.out.println("\n第" + count + "种:");
System.out.println("arr 数组:");
//打印 符合条件的 arr[] 数组
array(arr);
}else{
for (int j = 0;j < 8 ;j++ ) {
//j 表示列 循环遍历 第0-7列
arr[i] = j;
//验证是否符合八皇后规则
if (verify(arr,i)) {
//如果 验证返回true 则 递归调用 putQueen()方法
//继续 放置下一行的棋子位置(行和列:i 和 j) 并验证 位置是否符合八皇后规则
putQueen(arr,i + 1);
}
}
//如果 行为第i+1行 棋子 循环遍历 放置0——7列
//都不符合八皇后规则 即 verify(arr,i) 返回false
//则 不会执行 if里面的语句 putQueen(arr,i+1);
//即 不会继续下一行 放置棋子 而是回溯到 for语句
//继续遍历 数组列表 即 这一行的第2列
}
}
//一维数组变二维数组 并打印相对应的图形
public void array(int[] arr){
char[][] arr1 = new char[arr.length][arr.length];
for (int i = 0;i < arr1.length ;i++ ) {
for (int j = 0;j <arr1[i].length;j++ ) {
arr1[i][j] = '*';
arr1[i][arr[i]] = 'Q';
System.out.print(arr1[i][j] + " ");
}
System.out.println();
}
}
}