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("\n棋盘布置方案:");
82         N_Queens n_queens = new N_Queens(n);
83         scan.close();
84         System.out.print("总共解数为:"+ n_queens.methodNum);  
85     }  
86 }

 

posted on 2017-10-21 19:01  Arthurian  阅读(373)  评论(0编辑  收藏  举报