八皇后问题来自国际象棋当中的皇后的摆法问题,是一个经典的算法问题
国际象棋:
国际象棋是一个8 乘 8 的正方形棋盘,其中皇后 可以直线行走,斜线行走 都是不分上下左右和格数的
下图是一种可行的八皇后摆法:
所以,可归纳问题的条件为,8皇后之间需满足:
1.不在同一行上
2.不在同一列上
3.不在同一斜线上
思路:
对于八皇后问题,我们采用回溯算法来求解。
1、首先在第一行一列摆放一个皇后看是否符合要求
2、如果符合要求则在第二行的第一个位置开始依次尝试摆放第二个皇后以此类推
3、如果整行都不符合要求无法摆放一个皇后,则回退到上一个皇后,把上一个皇后再次往前移动一位
4、如此循环多次就可以得到一个皇后的摆放解法。
代码实现:
public class Queue {
//皇后数量
static int num=8;
//皇后的摆放数组
static int queenIndex[]=new int[num+1];
//当前记录的行
static int currentRow=1;
//当前试探的角标
static int beginIndex=1;
public static void main(String[] args) {
Nqueen();
}
private static void Nqueen() {
while (currentRow<=num){
for(int column =beginIndex;
column<=num ;
column++){
if(Place(currentRow,column)){
queenIndex[currentRow]=column;
currentRow++;
beginIndex=1;
show();
break;
}
if(column==num){
//最后一行还是不行,回溯
backQueen();
break;
}
}
show();
}
}
/**
* 递归回溯
*/
private static void backQueen() {
currentRow--;
beginIndex=queenIndex[currentRow]+1;
queenIndex[currentRow]=0;
if(beginIndex>num){
backQueen();
}
}
private static boolean Place(int targetRow, int targetColumn) {
if(queenIndex[targetRow]!=0){
//本行已经存在皇后
return false;
}
//判断有没有皇后是在目标列上的
for (int row=1;row<=num; row++){
if(queenIndex[row]==targetColumn){
return false;
}
}
//对角线判断行方向
//row++,colum++
for(int row = targetRow,colum=targetColumn; row<=num && colum<=num; row++,colum++){
if(queenIndex[row]==colum){
return false;
}
}
//row--,colum--
for(int row = targetRow,colum=targetColumn; row>0 && colum>0; row--,colum--){
if(queenIndex[row]==colum){
return false;
}
}
//row++,colum--;
for(int row = targetRow,colum=targetColumn; row<=num && colum>0; row++,colum--){
if(queenIndex[row]==colum){
return false;
}
}
//row--,colum++
for(int row = targetRow,colum=targetColumn; row>0 && colum<=num; row--,colum++){
if(queenIndex[row]==colum){
return false;
}
}
return true;
}
private static void show(){
StringBuffer line=new StringBuffer();
for (int i=1;i<=num; i++) {
line.append("————");
}
System.out.println(line.toString());
for (int row=1;row<=num; row++){
for (int column=1;column<=num; column++) {
if(queenIndex[row]==column){
System.out.print("Q");
}else{
System.out.print(" ");
}
System.out.print(" | ");
}
System.out.println();
System.out.println(line.toString());
}
}
}