C语言 八皇后问题

176 阅读2分钟

懒猫老师八皇后视频:

懒猫老师-C语言-递归函数-八皇后问题(搜索,回溯)_哔哩哔哩_bilibili


import org.junit.Test;

import java.util.Arrays;

public class HelloQueen {

        private int[] place = new int[8];                 // 表示棋盘的一行
        private boolean[] flag = new boolean[8];       // 纪录列的占用情况
        private boolean[] d1 = new boolean[15];    // 纪录主对角线的占用情况
        private boolean[] d2 = new boolean[15];  // 纪录副对角线的占用情况
        private int count; // 用于纪录成功放置8皇后的次数

        public HelloQueen() {
            // 初始化数组的值
            Arrays.fill(flag,true);
            Arrays.fill(d1,true);
            Arrays.fill(d2,true);
        }

        public void putQueen(int row){ // row表示当前行
            for(int col = 0; col < 8; col++){ // 从第row的第1列向第8列遍历
                if(flag[col] && d1[row-col+7] && d2[row+col]){
                    // 放置皇后
                    place[row] = col;
                    // 标记占用
                    flag[col] = false;      // col列被占用
                    d1[row-col+7] = false;  // 对应主对角线被占用
                    d2[row+col] = false;    // 对应副对角线被占用
                    // 当row < 7 时
                    if(row < 7){ // 递归调用
                        putQueen(row+1); // 继续放置下一行皇后
                    } else { // 当row == 7 时, 递归终止
                        print(); // 输出本次皇后的摆放位置
                    }

                    // 回溯,当代码执行到此处有2种情况:
                    // 1. 从putQueen()递归方法中返回, 并且在后续递归中未能找到合适位置, 则需要将row行,col列的所有标记清除, 并继续遍历row行col+1列。
                    // 2. 已经成功放置8个皇后, 即进入else语句, 同样也需要将row行,col列的所有标记清除,并返回至上一级方法调用处, 如果上一行皇后的位置不在最后一列,则会继续往后查找其它情况。如果上一行皇后在最后列, 则会继续返回上一行重复操作。
                    // 清除标记
                    flag[col] = true;
                    d1[row-col+7] = true;
                    d2[row+col] = true;
                }
            }
        }

        // 输出本次皇后摆放位置
        public void print(){
            // 纪录次数
            System.out.println("第" + (++count) + "次八皇后的排列方式: ");
            // 利用place数组中存放的信息, 还原为一个二维数组
            // 'Q'表示皇后,  '.' 表示空
            char[][] chessBoard = new char[8][8];
            for(int i = 0; i < 8; i++){
                Arrays.fill(chessBoard[i],'.');
                // 将第i行的第place[i]列置为Q
                chessBoard[i][place[i]] = 'Q';
            }

            // 遍历
            for(char[] chars : chessBoard){
                for(char chess : chars){
                    System.out.print(chess + "\t");
                }
                System.out.println();
            }
        }

        @Test
        public void testQueen(){
            putQueen(0); // 从第1行开始
        }
    }