八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
解题思路:
棋盘一共八行八列,按照列的原则放置这八个皇后,从第一列选择某一个位置放置第一个皇后,然后从第二列选择某一个位置放置第二个皇后,……依此放置下去。
要满足的条件就是:第一列可以任意选择位置放置;第二列选择的位置不能和第一列的皇后在同一行,同一斜线上;第三列选择的位置不能和第一列,第二列的皇后在同一行,同一斜线上;……依此类推下去
所以可以采用递归的方法来解决问题
具体思路如下:
放置第N列的皇后时,先遍历该列前面所有的皇后的位置,然后确定该列的八个格子哪些格子是不可以放置的(也就是会和前N列的皇后在同一行,同一斜线的所有位置),那么剩下的也自然就是可以放置的位置
例如:
上图的第4列在选择位置时,先遍历该列前面的所有皇后的位置,然后确定该列哪些格子不可以放置,那么剩下的就是可以放置的位置。
如此放置下去,就可以找出所有的解决方案
错误方案的情况就是某一列在选择位置时,发现该列的八个格子都不可放置,那么该方案就是错误方案
终止条件就是所有列都能找到位置放置皇后,这就是一个可行的解决方案。
采用一维数组存放每一列的皇后的位置,数组下标表示列,值表示行。
递归的核心代码如下:
每次递归的参数是一维数组place:皇后的放置位置,N: 本次需要寻找第几列的皇后位置
boolean findPlace(int[] place,int N){
// 记住本次要寻找的列,在寻找失败,回溯时会用到
int p = N;
// 终止条件
if(N > PI){
me++;
// 打印矩阵
System.out.println("第"+me+"种解法:");