N皇后问题
-
经典的回溯问题
8皇后问题(java算法实现),可以详细了解整一个的解题思路 -
解题思路:
- 关键是找到所满足的条件:
- 1.不在同一行上
- 2.不在同一列上
- 3.不在同一斜线上
- 4.不在同一反斜线上
- 想法很简单,在满足条件的情况下,一个个地去试就行了,但是怎么设计一个巧妙的办法去解决上面的条件呢?
- 根据高中学过的知识,斜线将满足条件,就是斜率为
+/-1
,即:设皇后(i,x)和(j,y),那么|i-j|!=|x-y|
- 解决同行同列问题以及斜线问题,巧妙的设计一个一维数组:
x[k]
,用k
代表行
,用x[k]
的值代表列
- 根据高中学过的知识,斜线将满足条件,就是斜率为
- 关键是找到所满足的条件:
-
代码:(算法书上的代码,就是精简)
/* * 题目: * n皇后问题 * 关键: * 用k作为行,用x[k]的值作为列,一维数组来表示二维数组 */ public class Main{ public static final int N=4;//代表多少个皇后的问题 public static void main(String[] args){ Main main=new Main(); main.queen(N+1); } int[] x=new int[N+1]; public void queen(int n){ int k=1; while(k>=1){ x[k]++;//在下一列摆放皇后k while(x[k]<n&&place(k)==1){ x[k]++;//进行试探下一列 } if(x[k]<n&&k==n-1){//得到一个解 for(int i=1;i<n;i++){ System.out.print(x[i]+" "); } System.out.println(); // return;//只求一个解,注释点,可以算多个,不满足条件会回溯到最顶层。 } if(x[k]<n&&k<n-1){//尚有皇后未摆放 k=k+1;//准备摆放下一个皇后 } else{ x[k--]=0;//重置x[k]回溯,重新摆放皇后k } } System.out.println("无解");//回溯完,都没有找到结果 } /* * 剔除同行,同列,主对角线,副对角线的情况 */ public int place(int k){ for(int i=0;i<k;i++){ if(x[i]==x[k]||Math.abs(i-k)==Math.abs(x[i]-x[k])){//是否违反约束条件 return 1; } } return 0; } }
-
总结:
刚开始遇到的问题,对着算法书上大,居然被一个字母
写错,而出不了答案,已经耗时了一天。。郁闷,以后命名规范,不能再用i,j,k
这些无意义的变量,变量名长点,有意义,便于擦错