n皇后问题
n皇后问题是利用回朔法解决的经典问题之一。
问题描述
在国际象棋中,皇后的位置很重要,设在n*n的棋盘上要放置n个皇后,使得任意一个皇后都无法直接吃掉其他皇后:任意两个皇后都不能在同一行或同一列或同一斜线上。
求满足上述条件的n个皇后的位置。
分析设计
这个问题如果我们采用暴力穷举的方法甚至是贪心算法的话,4皇后问题就会有1820种情况;8皇后问题就会存在131198072种情况,显然问题的规模是我们难以承受的。因此,我们必须采用新算法:回朔法。
我们按照最先最优条件向前搜索,一旦满足条件我们就往下一步走,当所有选择都不满足最优的条件时,就退回上一步重新进行选择,这个过程就是回溯。
在该问题当中:
由于背景是棋盘,所以我们很容易想到数据结构采用的是二维数组来记录皇后的位置。但实际上,在n*n的二维数组中,我们只标记n个位置,这就造成了很大的空间浪费。因此,我们采用一个更加节省空间的做法:
长度为n的一维数组queen[n],其中,数组下标表示棋盘的行数,数组的值表示棋盘的列数。
这样,也不会影响到皇后的放置问题。
我们再来考虑n个皇后放置的位置有要求的问题:皇后不能同行,同列,同斜线。
- 每一行只能放一个皇后:数组的值只能有一个(上面用一维数组的妙处之一);
- 每一列只能放一个皇后:数组下标也是唯一的(上面用一维数组的妙处之二);
- 每一斜线只能放一个皇后:这种情况有些复杂,我们可以通过画图找规律发现:设棋盘上任意两个皇后的位置为 ( i , j ) 、 ( k , l ) (i, j)、(k, l) (i,j)、(k,l),若两个黄后续处于一条斜线上时,满足:
i − k = j − l i - k = j - l i−k=j−l 或 i + j = k + l i + j = k + l