• 八皇后问题(递归)


    八皇后问题介绍

    八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.在8x8格的国际象棋上摆放8个皇后,使其不能互相攻击,即:任意两个皇后都不能处于同一行,同一列或同一斜线上,问有多少中摆法(92)

    八皇后问题算法思路分析

    1. 第一个皇后先放第一行第一列
    2. 第二个皇后放在第二行第一列,然后判断是否OK,如果不OK,继续放在第二列,第三列,依次把所有列都放完,找到一个合适的
    3. 继续放第3个皇后,还是第一列,第二列.......知道第8个皇后也能放在一个不冲突的位置,算是找到了一个正确的解
    4. 当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯,即将第一个皇后,放到第一列的所有正确解,全部得到.
    5. 然后回头继续第一个皇后放到第二列,后面继续循环执行1,2,3,4的步骤
    6. 示意图:

    说明

    • 理论上应该创建一个二维数组来表示棋盘,但是实际上可以通过一个算法,用一个一维数组即可解决问题.arr[8] = {1,4,7,5,2,6,1,3}
    • 对应arr下标,表示第几行,即第几个皇后,arr[i] = val,val表示第i+1个皇后,放在第i+1行的val+1列.

    代码实现

    public class queue8 {
        //定义一个max表示多少个皇后
        int max = 8;
        //定义一个数组,保存皇后放置位置的结果,比如arr={1,4,7,5,2,6,1,3}
        int[] arr = new int[max];
        static  int count = 0;
        public static void main(String[] args) {
            queue8 que = new queue8();
            que.check(0);
            System.out.println("总共有:"+ count);
    
        }
    
        /**
         * 放置第n+1个皇后
         *
         * @param n 皇后的下标
         */
        public void check(int n) {
            //结束递归的条件,n=8,表示0到7下标的皇后已经放置成功,即8个皇后都放置成功了
            if (n == 8) {
                print();  //打印放置结果
                return;
            }
            for (int i = 0; i < max; i++) {
                //把下标为n的皇后依次放在第1到8列的位置进行判断是否冲突
                arr[n] = i;
                if (judge(n)) { //不冲突
                    check(n+1); // 判断下一个
                }
            }
        }
    
        /**
         * @param n 皇后的下标
         * @return 不冲突返回true
         */
        private boolean judge(int n) {
            //判断冲突就是判断是否同列或者同斜线上
            for (int i = 0; i < n; i++) {
                //arr[i] == arr[n] 是否在同一行
                //Math.abs(arr[n] - arr[i]) == Math.abs(n - i)是否在同同一斜线
                if (arr[i] == arr[n] || Math.abs(arr[n] - arr[i]) == Math.abs(n - i)){
                    return false;
                }
            }
            return true;
        }
    
        //打印放置的结果
        private void print() {
            count++;
            for (int i : arr) {
                System.out.print(i + " ");
            }
            System.out.println();
        }
    }
    
    
  • 相关阅读:
    Linux C/C++ 利用scandir和alphasort遍历目录文件并排序
    C++11 多线程之互斥量、条件变量、call_once使用简介
    Win8 ApplicationModel Angkor:
    WinJS.Binding Angkor:
    WinJS.UI.Animation Angkor:
    WinJS.Class Angkor:
    WinJS.Application Angkor:
    WinJS.Promise Angkor:
    Rocket core ctrl_stalld和ctrl_killd
    Rocket core pipeline和replay
  • 原文地址:https://www.cnblogs.com/liuzhidao/p/13804740.html
Copyright © 2020-2023  润新知