• N皇后问题的实现


    N皇后问题是一个经典的问题,是回溯算法的典型案例。它是由国际西洋棋棋手马克斯·贝瑟尔于1848年提出的八皇后问题延伸而来的,具体要求如下:在N*N的方格棋盘放置N个皇后,使她们彼此不相互攻击,即任意2个皇后不允许在同一行、同一列、同一45°的斜线上,问有多少种摆法。

    Java:

     1 import java.util.Scanner;  
     2   
     3 /** 
     4  * n皇后问题解决 
     5  * 
     6  */  
     7 public class N_Queens {  
     8     /**下标i表示第几行,x[i]表示第i行皇后的位置,注意此处0行不用*/  
     9     public int[] x;  
    10     /**皇后的数目*/  
    11     public int queenNum;  
    12     /**解的数目*/  
    13     public int methodNum;
    14     
    15     N_Queens(int queenNum)
    16     {
    17         this.queenNum = queenNum;  
    18         this.x = new int[queenNum+1];//注意,这里我们从第1行开始算起,第0行不用  
    19         backtrack(1);//从第一个皇后开始递归  
    20     }  
    21       
    22     /** 
    23      * 一行一行的确定该行的皇后位置 
    24      * @param t 
    25      */  
    26     public void backtrack(int t)  
    27     {  
    28         if( t > queenNum) //如果当前行大于皇后数目,表示找到解了  
    29         {  
    30             methodNum++;//sum为所有的可行的解  
    31             //依次打印本次解皇后的位置  
    32             for(int m = 1; m <= queenNum; m++)
    33             {  
    34                //System.out.println(x[m]);//这一行用输出当递归到叶节点的时候,一个可行解  
    35                //这里只是为了好看才写成下面的  
    36                for(int k =1; k <= queenNum;k++)
    37                {  
    38                    if(k == x[m])
    39                    {  
    40                      System.out.print(x[m]+" ");   
    41                    }
    42                    else 
    43                    {  
    44                      System.out.print("* ");//用*表示没有被用到的位置  
    45                    }  
    46                }
    47                System.out.println();  
    48             }
    49             System.out.println();  
    50         }  
    51         else
    52         {  
    53             for(int i = 1;i <= queenNum;i++)  
    54             {  
    55                 x[t] = i;//第t行上皇后的位置只能是1-queenNum               
    56                 if(place(t)) //此处的place函数用来进行我们上面所说的条件的判断,如果成立,进入下一级递归,即放置下一个皇后  
    57                     backtrack(t+1);
    58             }  
    59         }  
    60     }  
    61       
    62     /** 
    63      * 判断第k行皇后可以放置的位置 
    64      * @param k k表示第k行,X[K]k表示第k行上皇后的位置 
    65      * @return boolean false表示此处不能放置皇后 
    66      */  
    67     public boolean place(int k)
    68     {  
    69         for (int j = 1; j < k; j++)  
    70             // 如果当前传入的第K行上的皇后放置的位置和其它皇后一个对角线(abs(x[k]- x[j])==abs(k-j)或一个直线上(x[j] == x[k])  
    71             if (Math.abs(x[k] - x[j]) == Math.abs(k - j) || (x[j] == x[k]))
    72                 return false;  
    73         return true;  
    74     }
    75 
    76     public static void main(String[] args) 
    77     {
    78         System.out.print("请输入皇后数:");
    79         Scanner scan=new Scanner(System.in);
    80         int n=scan.nextInt();
    81         System.out.println("
    棋盘布置方案:");
    82         N_Queens n_queens = new N_Queens(n);
    83         scan.close();
    84         System.out.print("总共解数为:"+ n_queens.methodNum);  
    85     }  
    86 }

    作者:耑新新,发布于  博客园

    转载请注明出处,欢迎邮件交流:zhuanxinxin@aliyun.com

  • 相关阅读:
    童年记忆
    展现、通讯、IO
    通电自动开机
    英雄每多屠狗辈,自古侠女出风尘(看黄金大劫案有感)
    反射整理学习<一>(转)
    在ASP.NET中跟踪和恢复大文件下载
    高内聚、低耦合
    你需要权限才能执行此操作
    WP7应用开发笔记(5) 通信设计
    一个简单的软件工程流程
  • 原文地址:https://www.cnblogs.com/Arthurian/p/7695243.html
Copyright © 2020-2023  润新知