八皇后问题JAVA解法,思路清晰简单!

八皇后问题来自国际象棋当中的皇后的摆法问题,是一个经典的算法问题

国际象棋:

             国际象棋是一个8 乘 8 的正方形棋盘,其中皇后 可以直线行走,斜线行走   都是不分上下左右和格数的

下图是一种可行的八皇后摆法:

所以,可归纳问题的条件为,8皇后之间需满足:

             1.不在同一行上

             2.不在同一列上

             3.不在同一斜线上

思路:

   对于八皇后问题,我们采用回溯算法来求解。

1、首先在第一行一列摆放一个皇后看是否符合要求

2、如果符合要求则在第二行的第一个位置开始依次尝试摆放第二个皇后以此类推

3、如果整行都不符合要求无法摆放一个皇后,则回退到上一个皇后,把上一个皇后再次往前移动一位

4、如此循环多次就可以得到一个皇后的摆放解法。

代码实现:



public class Queue {
    //皇后数量
    static int num=8;
    //皇后的摆放数组
    static int queenIndex[]=new int[num+1];
    //当前记录的行
    static int currentRow=1;
    //当前试探的角标
    static int beginIndex=1;

    public static void main(String[] args) {

        Nqueen();

    }

    private static void Nqueen() {


        while (currentRow<=num){

            for(int column =beginIndex;
                column<=num ;
                column++){

                if(Place(currentRow,column)){
                    queenIndex[currentRow]=column;
                    currentRow++;
                    beginIndex=1;
                    show();
                    break;
                }

                if(column==num){
                    //最后一行还是不行,回溯
                    backQueen();
                    break;
                }
            }
            show();
        }
    }

    /**
     * 递归回溯
     */
    private static void backQueen() {
        currentRow--;
        beginIndex=queenIndex[currentRow]+1;
        queenIndex[currentRow]=0;
        if(beginIndex>num){
            backQueen();
        }

    }

    private static boolean Place(int targetRow, int targetColumn) {

        if(queenIndex[targetRow]!=0){
            //本行已经存在皇后
            return false;
        }

        //判断有没有皇后是在目标列上的
        for (int row=1;row<=num; row++){
            if(queenIndex[row]==targetColumn){
                return false;
            }
        }
        //对角线判断行方向
        //row++,colum++

        for(int row = targetRow,colum=targetColumn; row<=num && colum<=num; row++,colum++){
            if(queenIndex[row]==colum){
                return false;
            }
        }
        //row--,colum--
        for(int row = targetRow,colum=targetColumn; row>0 && colum>0; row--,colum--){
            if(queenIndex[row]==colum){
                return false;
            }
        }
        //row++,colum--;
        for(int row = targetRow,colum=targetColumn; row<=num && colum>0; row++,colum--){
            if(queenIndex[row]==colum){
                return false;
            }
        }
        //row--,colum++
        for(int row = targetRow,colum=targetColumn; row>0 && colum<=num; row--,colum++){
            if(queenIndex[row]==colum){
                return false;
            }
        }
        return true;
    }

    
    private static void show(){
        StringBuffer line=new StringBuffer();
        for (int i=1;i<=num; i++) {
            line.append("————");
        }
        System.out.println(line.toString());

        for (int row=1;row<=num; row++){
            for (int column=1;column<=num; column++) {

                if(queenIndex[row]==column){
                    System.out.print("Q");
                }else{
                    System.out.print(" ");
                }
                System.out.print(" | ");
            }
            System.out.println();
            System.out.println(line.toString());

        }
    }

}

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值