问题:把N个国际象棋中的皇后摆放在N*N的棋盘上,使之不能相互攻击。问有多少种摆法?
问题很简洁,却很难让人琢磨透彻,现在我就带你用一种简洁而有效的方法计算出结果。
问题分析:
--N个皇后不能相互攻击,也就是说每行上有且只能有一个皇后,且其他行不允许有与之同列、同斜线的皇后;
问题本质:
仔细思考该问题,我们会发现第k行的皇后可能位置会被前k-1行的皇后所决定,因此我们考虑用循环来遍历每一行的皇后所有可能的位置。但是问题来了,我们不知道具体有多少给皇后,所以不知道需要多少重循环,那么我们有没有解决办法呢?当然是有的,我们可以用递归,使用递归就能解决循环未知这一问题。
问题技巧:
根据问题的本质,我们需要确定该问题的递归终止条件以及怎样由已知的k-1行推得未知的第k行。在一个解中,我们如何判断这是一个正解呢?第一,我们必须要确定该解必须包含了所有的皇后;第二,所有的皇后都不能相互攻击。有了这两个限制,我们很容易就能确定出递归的终止条件:当所有皇后都摆放了,递归结束。而后我们再考虑,如果已知了前k-1行的皇后正确摆放(也就是互不攻击),如何推出第k行。当前k-1行都摆放好后,我们确定第k行是很容易的:只需考虑第k行的摆放位置与前k-1行不冲突即可(说了像没说,不过确实如此),也就是说,如果我们采用一个有N个元素的一维数组quen[N]来存放皇后,数组的每一个元素取值即为该下表所表示的皇后的位置,那么每一个元素的取值范围就都是(0,N-1)。当我们要看第k行的皇后是否与前k-1行冲突时,只用比较以k为下表的元素的值是否与k-i(i<k)为下标的元素值相等(同一列)或者quen[k-i](quen[k+i])是否与i相等(斜着)即可。
问题解:
见 实例代码 专栏 《N皇后--全代码》