问题简介:
要求在一个8*8的棋盘上放置8个皇后,使任意两个皇后都不同行不同列且不在同一条斜对角线上。采用递归和回溯的思想解决这一问题是较为直观的。一开始,棋盘上的任意格子都可落子,因此可任意选择第一个皇后的位置。放置了第一个皇后之后,棋盘上的可落子格子的分布将发生改变,然后在可以落子的格子中选择一个放置第二个皇后,重复以上步骤,若发生第n个皇后无格子可放置,则回溯到上一步,更改第n-1个皇后的位置,直至第8个皇后的位置确定下来,则结束寻找,打印出方案。
本文中使用一个8行8列的数组来表示棋盘,0表示该位置未落子,1~8表示八个皇后。具体实现代码如下:
public class EightQueen {
public static int[][] chessBoard = new int[8][8];//8*8棋盘
public static int[][] ifAvailable = new int[8][8];//标记棋盘上的格子是否可落子
public static int count = 0;//记录已确定位置的皇后数量
public static void main(String[] args){
//初始化
for(int m=0; m<8; m++){
for(int n=0; n<8; n++){
chessBoard[m][n] = 0;
ifAvailable[m][n] = 0;
}
}
arrange(1,3);//开始落子,可以从棋盘上任意位置开始,如arrange[2][7]等
}
public static void arrange(int i, int j){
count++;
chessBoard[i][j] = count;
int[][] changed = new int[8][8];
for(int m=0; m<8; m++){
for(int n=0; n<8; n++){
changed[m][n] = 0;
}
}
for(int m=-7; m<8; m++){
if(m>=0&&ifAvailable[i][m]==0){//与皇后同行的格子不可落子
ifAvailable[i][m] = 1;
changed[i][m] = 1;//
}
if(m>=0&&ifAvailable[m][j]==0){//与皇后同列的格子不可落子
ifAvailable[m][j] = 1;
changed[m][j] = 1;
}
//与皇后
if(i+m>=0&&i+m<8&j+m>=0&&j+m<8&&ifAvailable[i+m][j+m]==0){
ifAvailable[i+m][j+m] = 1;
changed[i+m][j+m] = 1;
}
if(i+m>=0&&i+m<8&j-m>=0&&j-m<8&&ifAvailable[i+m][j-m]==0){
ifAvailable[i+m][j-m] = 1;
changed[i+m][j-m] = 1;
}
}
if(count==8){//一旦第八个皇后已经确定位置,则打印方案,结束程序
for(int m=0; m<8; m++){
for(int n=0; n<8; n++){
System.out.print(chessBoard[m][n]+" ");
}
System.out.println();
}
System.exit(0);//若删除该行,则可打印出所有的方案,因方案数量庞大造成输出过多,故不作此处理
}
else{//如果还没有将所有皇后的位置确定,则继续寻找
for(int m=0; m<8; m++){
for(int n=0; n<8; n++){
if(ifAvailable[m][n]==0){
arrange(m,n);
}
}
}
}
//在回溯之前,应将本轮改变过的状态恢复为原样
count--;
chessBoard[i][j] = 0;
for(int m=-7; m<8; m++){
if(m>=0&&changed[i][m]==1){
ifAvailable[i][m] = 0;
}
if(m>=0&&changed[m][j]==1){
ifAvailable[m][j] = 0;
}
if(i+m>=0&&i+m<8&j+m>=0&&j+m<8&&changed[i+m][j+m]==1){
ifAvailable[i+m][j+m] = 0;
}
if(i+m>=0&&i+m<8&j-m>=0&&j-m<8&&changed[i+m][j-m]==1){
ifAvailable[i+m][j-m] = 0;
}
}
}
}
输出:
0 2 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 0 3 0 0
0 0 0 0 0 0 0 4
0 0 5 0 0 0 0 0
6 0 0 0 0 0 0 0
0 0 0 0 0 0 7 0
0 0 0 0 8 0 0 0