0
点赞
收藏
分享

微信扫一扫

八皇后问题及其解决方案

毅会 2022-01-28 阅读 77

一.八皇后问题描述

八皇后问题(英文:Eight queens),是由国际象棋棋手马克斯·贝瑟尔于1848年提出的问题,是回溯算法的典型案例。

问题表述为:在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

二.解决思路

1.利用数组来描述八皇后问题

为了方便表达,可以用一个8*8的二数组来代表棋盘,然而实际上只需要也只能够摆放八个棋子,所以也可以用一个容量为8的一维数组来表示每一行的第几列用来摆放皇后。

例如arr[] ={0,4,7,5,2,6,1,3}则表示分别在第一行的第一列,第二行的第五列摆放皇后等等,即

queen
queen
queen
queen
queen
queen
queen
queen

2.定义摆放的规则

可以定义一个isright函数来判断摆放的位置是否正确

private boolean isright(int n){//n表示传入的是第几行的皇后
        boolean isright=true;
        for(int i=0;i<n;i++){
            if(arr[i]==arr[n]||Math.abs(n-i)==Math.abs(arr[n]-arr[i])){//斜率为正负一,或者在同一列
                isright= false;
                break;
            }
        }
        return isright;
    }

3.如何摆放

定义一个add函数,利用递归的原理一行一行的摆放

private void add(int n){//n表示放的是哪一列
		if(n==max){//全部摆放完毕
			printq();//输出摆放结果
			return;
		}
		for(int i=0;i<max;i++){
			//从第0列开始,一列一列的试放
			arr[n]=i;
			if(isright(n)){
				//利用isright方法,检验摆放的位置是否正确,如果正确,则继续摆放下一行
				add(n+1);
			}
		}
	}

最后,只需要再定义一个输出摆放结果的方法即可

private void printq(){
		count++;//用来记录输出了多少次结果,即有多少个正确方案
		for (int element : arr) {
			System.out.printf(element+" ");
		}
		System.out.println();
	}

三.总结

解决该问题利用递归的思想,一个一个试错来得到最后的结果

//八皇后问题
public class Queen8 {
	int max=8;
	int arr[]=new int[max];
	static int count;
	public static void main(String[] args) {
		Queen8 solution=new Queen8();
		solution.add(0);
		System.out.println("总共有"+count+"种方法");
	}
	//放置第n行皇后
	private void add(int n){
		if(n==max){
			printq();
			return;
		}
		for(int i=0;i<max;i++){
			arr[n]=i;
			if(isright(n)){
				add(n+1);
			}
		}
	}
	//检测该皇后是否和前面已经摆放的皇后冲突
	private boolean isright(int n){
		boolean isright=true;
		for(int i=0;i<n;i++){
			if(arr[i]==arr[n]||Math.abs(n-i)==Math.abs(arr[n]-arr[i])){
				isright= false;
				break;
			}
		}
		return isright;
	}
	//输出皇后摆放位置
	private void printq(){
		count++;
		for (int element : arr) {
			System.out.printf(element+" ");
		}
		System.out.println();
	}
}
举报

相关推荐

0 条评论