8皇后问题(Java版)

八皇后问题,是一个古老而著名的问题,是回溯算法的典型例题。该问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

在这里插入图片描述

解题思路:

  • 采用穷举的方法,从棋盘第一行的第一个位置开始,检验皇后之间是否会相互攻击。如果会,继续判断下一格是否会互相攻击,如果不会互相攻击则在这个位置进行标记,并开始遍历下一行,查找满足条件的皇后位置,直到不能再继续放置皇后为止。
  • 这时,我们可以做出简单的判断,当皇后数量为每行各一个时,它是满足摆放策略的,当没有放到最后一行时,这种情况是不满足条件的。当然满足摆放皇后位置的方法并不止一种,我们不能在查找过一次方案后就停止查找,因此我们在进行逐层遍历时要引入回溯的思想,再每次标记过位置查找下一行之后,我们还要记得取消我们的标记,这样才可以保证找到全部符合条件的情况。

例题:给定一个整数 n,打印出所有不同的 n 皇后问题的解决方案。每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。

public class EightQueen {
	
	public static void main(String[]args) {
		char[][] ch= new char[8][8];       //定义n*n的棋盘
		for(int i=0;i<ch.length;i++) {     //对每个棋盘位置都标记为'.'
			for(int j=0;j<ch.length;j++) {
				ch[i][j]='.';
			}
		}
		solveNQueens(0,ch);                //调用递归的函数,从棋盘的第一行开始
	}
		
	public static void solveNQueens(int row,char[][] ch2) {
        //如果遍历的行数大于棋盘的行数,说明我们遍历到了最后一行,满足要求
		if(row>=ch2.length) {             
			for(int i=0;i<ch2.length;i++) {   //打印这一种方案
				for(int j=0;j<ch2.length;j++) {
					System.out.print(ch2[i][j]);
				}
				System.out.println();
			}
			System.out.println();
		}
		
		for(int i=0;i<ch2.length;i++) {      //依次逐行遍历,
			if(check(row,i,ch2)) {
				ch2[row][i]='Q';		     //在每行的标记满足条件的皇后位置
				solveNQueens(row+1, ch2);    //递归,调用下一行
				ch2[row][i]='.';             //取消我们之前的标记,避免影响下一次查找
			};
		}
    }

    //判断该位置是否适合标记皇后
	private static boolean check(int row, int index, char[][] ch2) {
		
		//值得注意的是因为我们采用的逐层遍历的思想,我们不需要再复杂的写一个不在同一行、同一列、同一斜线上的复杂函数
		//我们只需要考虑,该位置的上方,左上方,右上方是否有冲突的皇后就可以了
		int rightTop=index,leftTop=index;
		for(int i=row-1;i>=0;i--) {
			rightTop++;
			leftTop--;
			if(ch2[i][index]=='Q')return false;
			if(rightTop<ch2.length) {
				if(ch2[i][rightTop]=='Q')return false;		
			}
			if(leftTop>=0) {
				if(ch2[i][leftTop]=='Q')return false;			
			}
		}
		return true;
	}

}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙源lll

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值