(Java)使用递归方法解决八皇后问题(超详细!)

最近在学习递归方法,所以就接触到了很经典的八皇后问题。

递归就是方法自己调用自己,每次调用时传入不同的变量。

八皇后问题是是由国际象棋棋手马克斯·贝瑟尔于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();
			}

		}

	

}

结果如图所示:

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java八皇后问题是一个经典的回溯算法问题,目标是在一个8x8的棋盘上放置8个皇后,使得它们互相之间不能攻击到对方。在这个问题中,皇后可以攻击同一行、同一列以及同一对角线上的其他皇后。 递归解决八皇后问题的常用方法之一。下面是一个简单的Java代码示例: ```java public class EightQueens { private static final int SIZE = 8; private static int[] queens = new int[SIZE]; public static void main(String[] args) { solve(0); } private static void solve(int row) { if (row == SIZE) { printQueens(); return; } for (int col = 0; col < SIZE; col++) { if (isValid(row, col)) { queens[row] = col; solve(row + 1); } } } private static boolean isValid(int row, int col) { for (int i = 0; i < row; i++) { if (queens[i] == col || queens[i] - col == i - row || queens[i] - col == row - i) { return false; } } return true; } private static void printQueens() { for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { if (queens[i] == j) { System.out.print("Q "); } else { System.out.print(". "); } } System.out.println(); } System.out.println(); } } ``` 在这段代码中,我们使用一个一维数组`queens`来表示每一行皇后所在的列数。`solve`方法递归的核心部分,它尝试在当前行的每一列放置皇后,并递归地调用下一行。`isValid`方法用于判断当前位置是否可以放置皇后,它检查同一列、同一对角线上是否已经存在皇后。当放置完最后一行的皇后时,我们就找到了一个解,通过`printQueens`方法打印出棋盘。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值