1. 程式人生 > >java利用遞迴解決八皇后問題

java利用遞迴解決八皇后問題

問題簡介:

要求在一個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