1. 程式人生 > >易理解java代碼8皇後問題

易理解java代碼8皇後問題

post 2種 行數 本質 一行 [] 想是 util 都是

馬上就要藍橋杯比賽了,我這些算法還是不會,確實有點慌,今天一天早上睡到很晚不願起床,然後才開始研究8皇後問題。這也是典型的回溯與遞歸問題。其實本質上和馬踏棋盤問題非常類似,八皇後問題呢,就是要判斷主對角線,副對角線,橫排和豎排不能有皇後。這個是這個問題的著重點。先來看下八皇後問題吧。

1.問題描述:

    在8*8的棋盤中放8個皇後,使得每個皇後不能放在同一行,同一列,同一主對角線上(左下斜),同一副對角線上(右上斜)。

2.輸入: 無(當然也可以優化求任意皇後,這個就不是重點了)

3.輸出示例:

     1 * * * * * * *
    * * * * 2 * * *
     * * * * * * * 3
     * * * * * 4 * *
     * * 5 * * * * *
     * * * * * * 6 *
     * 7 * * * * * *
    * * * 8 * * * *

    ===============

    1 * * * * * * *
    * * * * * 2 * *
    * * * * * * * 3
    * * 4 * * * * *
    * * * * * * 5 *
    * * * 6 * * * *
    * 7 * * * * * *
    * * * * 8 * * *

    ===============

    ...........

    共有92種方法

4.算法思路:

    這題整體思想是用到遞歸與回溯,與馬踏棋盤非常類似,但是比馬踏棋盤問題要難,因為得判斷對角線是否沖突,我這裏判斷是用一個vis[3][20]數組,為什麽開始是3呢,因為本身是要判斷4個方向不能有皇後的,但是遞歸是每一列,每一列的遞歸x,x+1.....這樣必然不會在同一列上造成有皇後,則只需要另外3個方向,0表示同一行有皇後,1表示主對角線有皇後,2表示副對角線上有皇後。另外呢,怎麽判斷這些對角線上是否有皇後 呢? 如果我在第x列,第i行放了元素,那麽vis[0][i] = 1表示我在第i行放了元素了。vis[1][x+i] = 1,表示如果我在第x列,第i行放了皇後,那麽副對角線上,第x+1列,i-1行數就不能放皇後,第x-1列,第i+1行就不能放皇後,正好都是在副對角線上。vis[2][x-i+8] = 1,表示如果x==i了,那麽恒等於vis[2][8] = 1就不能放了,即是主對角線。有了這三個條件既可以了。

5.代碼如下:
import java.util.Scanner;

public class EightQueen {
static int qipan[][] = new int[8][8];
static int count = 0;
static int step = 1;
static int vis[][] = new int[3][20]; //三種情況主對角線,副對角線,行有沒有被占用。
public static void main(String[] args) {
//初始化棋盤
for(int i=0;i<8;i++){
for(int j=0;j<8;j++){
qipan[i][j] = 0;
}
}
for(int i=0;i<vis.length;i++){
for(int j=0;j<vis[i].length;j++){
vis[i][j] = 0;
}
}

move(0);
//從第0個位置開始放第一個皇後,沒得說,只要求出皇後的位置,和擺放的數量即可。
System.out.println("count = " + count);
}
public static void move(int x) {
int next_x = x+1;
if(step>8){
for(int i=0;i<8;i++){
for(int j=0;j<8;j++){
if(qipan[i][j] == 0){
System.out.printf("%3c",‘*‘); //把沒有皇後,棋盤是0的位置用*輸出,顯得好看一點
}else{
System.out.printf("%3d",qipan[i][j]);
}

}
System.out.println();
}
System.out.println("========================");
count++;
}else{
for(int i=0;i<8;i++){
if(vis[0][i]==0 && vis[1][x+i]==0 && vis[2][x-i+8]==0){//滿足擺放條件
qipan[x][i] = step;
step++;
vis[0][i]=1; vis[1][x+i]=1; vis[2][x-i+8]=1;
move(next_x);
qipan[x][i] = 0;
vis[0][i]=0; vis[1][x+i]=0; vis[2][x-i+8]=0;
step--;

}
}
}
}
}

易理解java代碼8皇後問題