zoukankan      html  css  js  c++  java
  • 递归八皇后问题(回溯算法)

    八皇后问题介绍

      八皇后问题是国际西洋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能相互攻击,即:任意两个皇后不能处于同一行、同一列或者同一斜线上,问有多少种摆法(共92种)。

    八皇后问题算法思路分析

      1.第一个皇后先放在第一行第一列

      2.第二个皇后放在第二行第一列,然后判断是否可行,如果不可行,继续放在第二列、第三列,依次把所有列都放完,找到一个合适的位置。

      3.继续第三个皇后,还是第一列、第二列......直到第8个皇后也能放在一个不冲突的位置上,就找到了一个正确的解法

      4.当得到一个正确的解法是,在栈回退到上一个栈时,就会开始回溯,即将第一个皇后,放到第一列的所有正确解法全部得到。

      5.然后回头继续第一个皇后放到第二列,后面继续循环执行1,2,3,4步骤。、

    实现代码

    package com.atxihua;
    
    public class Queue8 {
        //定义一个max表示共有多少个皇后
        int max=8;
        //定义数字array,保存皇后存放位置的结果,比如arr={0,4,7,5,2,6,1,3}
        int[] array=new int[max];
        static int count=0;
        static int judgeCount=0;
        //测试八皇后是否正确
        public static void main(String[] args) {
            Queue8 queue8=new Queue8();
            queue8.check(0);
            System.out.println("一共有"+count+"种解法");//92
            System.out.println("一共发生"+judgeCount+"次冲突");//15720
        }
        //编写一个方法,放置第n个皇后
        //特别注意:check是每一次递归时,进入到check中都有for(int i=0;i<max;i++),因此会回溯
        private void check(int n) {
            if(n==max){
                //n=8,说明8个皇后已经放好
                print();
                return;
            }
            //依次放入皇后,并判断是否冲突
            for(int i=0;i<max;i++){
                //先把当前这个皇后n,放到该行的第1列
                array[n]=i;
                //判断当放置第n个皇后到第i列时,是否发生冲突
                if(judge(n)){//不冲突
                    //接着放n+1个皇后,即开始递归
                    check(n+1);
                }
                //如果冲突,就继续执行array[n]=i;即将第n个皇后,放置在本行的后移一个位置
            }
        }
        //当我们放置第n个皇后,就去检测该皇后是否和前面已经摆放的皇后冲突
        private boolean judge(int n) {
            judgeCount++;
            for(int i=0;i<n;i++){
                /*
                * 说明
                * array[i]==array[n]表示判断第n个皇后是否和前面的n-1个皇后在同一列
                * Math.abs(n-i)==Math.abs(array[n]-array[i])表示判断第n个皇后是否和第i个皇后是否在同一斜线
                * n=1 放置第2列 n=1 array[1]=1
                * Math.abs(1-0)==1 Math.abs(array[n]-array[i])=Math.abs(1-0)=1
                * 判断是否在同一行,没有必要,n每次都在递增
                * */
                if(array[i]==array[n]||Math.abs(n-i)==Math.abs(array[n]-array[i])){
                    return false;
                }
            }
            return true;
        }
    //写一个方法,可以将皇后摆放的位置输出
        private void print() {
            count++;
            for(int i=0;i<array.length;i++){
                System.out.print(array[i]+" ");
            }
            System.out.println();
        }
    }

    部分运行结果:

  • 相关阅读:
    To select the file to upload we can use the standard HTML input control of type
    Cascading Menu Script using Javascript Explained
    网站首页head区代码规范
    轻松掌握 Java 泛型
    JDK 5.0 中的泛型类型学习
    如何在firefox下获取下列框选中option的text
    是同步方法还是 synchronized 代码? 详解多线程同步规则
    javascript select option对象总结
    Select的动态取值(Text,value),添加,删除。兼容IE,FireFox
    javascript在ie和firefox下的一些差异
  • 原文地址:https://www.cnblogs.com/ftx3q/p/15726790.html
Copyright © 2011-2022 走看看