描述
给一个n*n的棋盘,在棋盘上放置n个皇后
要求是:皇后之间不能共行、列、斜线
解决方法
遍历
在任意一种正确的方案中,每一行有且只有一个皇后。
当确定了某行中皇后的位置,便向下一行探索合法的皇后位置,直到最后一行,如果n个皇后放置完毕,则算作一种方案,若未放完则该方案不合法。
方法细节
初始时,将第一行的每一格作为一个方案的开始步骤,以步骤集的方式加入队列。
然后以一个步骤集为前提,将下一行中每一个合法的位置,添加到步骤集上,并将该步骤集加入队列。
直到某一步骤集的步数为n或者队列为空,循环结束。
判断棋格合法的标准是,该棋格不与步骤集中的棋格共列、斜线。
/*
* n皇后问题
*/
public int nQueen(int n)
{
Queue<int[][]> q = new LinkedList<int[][]>();
for(int i=0; i<n; i++)//初始时将第一行的每一格都作为一种方案的起始
q.add(new int[][] {{0, i}});
while(!q.isEmpty())
{
int[][] steps = q.peek();//取一种方案为前提
int len = steps.length;
if(len==n)//当方案的步骤数等于n循环结束
break;
else
q.poll();
for(int i=0; i<n; i++)//以该方案为前提探索下一行的每一个棋格
{
int[] step = new int[]{len, i};
if(judge(step, steps))//判断当前棋格是否合法
putIn(step, steps, q);//将合法的棋格添加到步骤集,并将步骤集加入队列
}
}
return q.size();
}
private void putIn(int[] step, int[][] steps, Queue<int[][]> q) {
int [][] newM = new int[steps.length+1][];
for(int i=0; i<steps.length; i++)//把steps克隆一份
newM[i] = steps[i].clone();
newM[steps.length] = step;//再把step添加到棋谱中
q.add(newM);//把新棋谱加入队列
}
private boolean judge(int[] step, int[][] steps) {
for(int[] s:steps)
if(s[1]==step[1] || Math.abs(s[0]-step[0])==Math.abs(s[1]-step[1]))//判断竖直方向和对角线方向上的合法性
return false;
return true;
}