zoukankan      html  css  js  c++  java
  • 八皇后问题

    八皇后问题是数学家高斯于1850年提出的,这是一个典型的回溯算法的问题。八皇后问题的大意如下:

      国际象棋的棋盘有8行8列共64个单元格,在棋盘上摆放8个皇后,使其不能互相攻击,也就是说任意两个皇后都不能处于同一行、同一列或同一斜线上。问总共共有多少种摆放方法,每一种摆放方式是怎样的。

      目前,数学上可以证明八皇后问题总共有92种解。

    1. 八皇后问题算法

    首先来分析八皇后问题,这个问题的关键是,8个皇后中任意两个皇后都不能处于同一行、同一列或同一斜线上。可以采用递归的思想来求解八皇后问题,算法的设计思路如下:

    (1)首先在棋盘的某个位置放置一个皇后。

    (2)然后,放置下一个皇后。

    (3)此时,判断该皇后是否与前面已有皇后形成互相攻击,若不形成互相攻击,则重复第二个步骤,继续放置下一列的皇后。

    (4)当放置完8个不形成攻击的皇后,就找到一个解,将其输出。

    这里可以使用递归的方式来实现。可以按照此思路来编写相应的八皇后问题的求解算法,代码示例如下:

        static int iCount=0;    //全局变量
        static int[] WeiZhi=new int[8];    //全局数组
        static void Output(){
            int i,j,flag=1;
            System.out.printf("第%2d种方案(★表示皇后):
    ", ++iCount);    //输出序号
            System.out.printf("     ");
            for(i=1;i<=8;i++){
                System.out.print("▁");
            }
            System.out.println();
            for(i=0;i<8;i++){
                System.out.print("▕");
                for(j=0;j<8;j++){
                    if(WeiZhi[i]-1==j){
                        System.out.print("★");    //皇后的位置
                    }else{
                        if(flag<0){
                            System.out.print("     ");    //棋格
                        }else{
                            System.out.print("■");    //棋格
                        }
                    }
                    flag=-1*flag;
                }
                System.out.println("▏ " );
                flag=-1*flag;
            }
            System.out.print("     ");
            for(i=1;i<=8;i++){
                System.out.print("▔");
            }
            System.out.println();
        }
        
        //算法
        static void eightQueen(int n){
            int i,j;
            int ct;    //用于判断是否冲突
            if(n==8){
                Output();    //输出求解结果
                return;
            }
            for(i=1;i<=8;i++){    //试探
                WeiZhi[n]=i;    //在该列的第i行上放置
                //判断第n个皇后是否与前面的皇后形成攻击
                ct=1;
                for(j=0;j<n;j++){
                    if(WeiZhi[n]==WeiZhi[j]){    //形成攻击
                        ct=0;
                    }else if(Math.abs(WeiZhi[j]-WeiZhi[n])==(n-j)){    //形成攻击
                        ct=0;
                    }else{
                        
                    }
                }
                if(ct==1)    //没有冲突,就开始下一列的试探
                    eightQueen(n+1);    //递归调用
            }
        }

    2. 八皇后问题求解

    完整的八皇后求解程序代码如下:

    package com.cn.suanfaquti;
    
    public class EightQueen {
        static int iCount=0;    //全局变量
        static int[] WeiZhi=new int[8];    //全局数组
        static void Output(){
            int i,j,flag=1;
            System.out.printf("第%2d种方案(★表示皇后):
    ", ++iCount);    //输出序号
            System.out.printf("     ");
            for(i=1;i<=8;i++){
                System.out.print("▁");
            }
            System.out.println();
            for(i=0;i<8;i++){
                System.out.print("▕");
                for(j=0;j<8;j++){
                    if(WeiZhi[i]-1==j){
                        System.out.print("★");    //皇后的位置
                    }else{
                        if(flag<0){
                            System.out.print("     ");    //棋格
                        }else{
                            System.out.print("■");    //棋格
                        }
                    }
                    flag=-1*flag;
                }
                System.out.println("▏ " );
                flag=-1*flag;
            }
            System.out.print("     ");
            for(i=1;i<=8;i++){
                System.out.print("▔");
            }
            System.out.println();
        }
        
        //算法
        static void eightQueen(int n){
            int i,j;
            int ct;    //用于判断是否冲突
            if(n==8){
                Output();    //输出求解结果
                return;
            }
            for(i=1;i<=8;i++){    //试探
                WeiZhi[n]=i;    //在该列的第i行上放置
                //判断第n个皇后是否与前面的皇后形成攻击
                ct=1;
                for(j=0;j<n;j++){
                    if(WeiZhi[n]==WeiZhi[j]){    //形成攻击
                        ct=0;
                    }else if(Math.abs(WeiZhi[j]-WeiZhi[n])==(n-j)){    //形成攻击
                        ct=0;
                    }else{
                        
                    }
                }
                if(ct==1)    //没有冲突,就开始下一列的试探
                    eightQueen(n+1);    //递归调用
            }
        }
        
        public static void main(String[] args) {
            System.out.println("八皇后问题求解!");
            System.out.println("八皇后问题排列方案:");
            eightQueen(0);    //求解
    
        }
    
    }

    部分输出结果如下:

  • 相关阅读:
    【ybtoj高效进阶 21173】简单区间(分治)
    【ybtoj高效进阶 21170】投篮训练(贪心)(线段树)(构造)
    【ybtoj高效进阶 21172】筹备计划(线段树)(树状数组)
    【ybtoj高效进阶 21168】打字机器(Trie树)(LCA)(值域线段树)
    【ybtoj高效进阶 21169】毁灭计划(分类讨论)(树形DP)
    【ybtoj高效进阶 21167】旅游计划(基环树)(DP)(单调队列)
    Day-15 面向对象02 成员
    Day-14 初识面向对象
    Day 13 内置函数(点击网址进入思维导图)、递归、二分法
    Day12 生成器函数-推导式
  • 原文地址:https://www.cnblogs.com/gaopeng527/p/4513089.html
Copyright © 2011-2022 走看看