八皇后問題(n-皇后問題)
阿新 • • 發佈:2020-09-23
# JAVA
作為一道經典的題目,那必然要用經典的dfs來做
dfs:深度優先搜尋————縱向搜尋符合條件的內容,走到底時回到上一個路口再走到底再回去,套娃至結束。
條件:在一個n*n的國際棋盤上擺放n個皇后,任意一個皇后所在位置的四條線(橫、縱、對角、副對角)不能放置其他皇后。
### 思路:
可以想到每放置一個皇后我們就要移動到下一行,所以不需要對該行進行狀態判斷。只需要對列、主副對角線進行判斷就可以了。
**那麼問題來了**如何用一個值代表一條線呢
**列**: 沒什麼好說的直接 col[y]
平面座標系中的副對角線實際上也就是二維陣列中的主對角線
所以得出:
任意一條副對角線公式為
y = x + b => b = y - x + n(陣列中沒有負數所以平移n位)
任意一條主對角線公式為
y = - x + b => b = x + y
**主對角線**: diagonal[x+y]
**副對角線**: cdiagonal[y-x+n]
b 是任意一條主副對角線到(0,0)的截距
那我們就可以通過一個一維陣列來表示二維陣列中的每一條主副對角線
至多會有2*n條主或副對角線,所以只需要開2n的空間就可以了
下面圖隨便看看
![](https://s1.ax1x.com/2020/09/23/wxphZj.png)
#### 程式碼奉上
```
import java.util.*;
public class Main{
static int n = 0;
static String[][] path = new String[10][10];
static boolean[] col = new boolean[20];
static boolean[] diagonal = new boolean[20];
static boolean[] cdiagonal = new boolean[20];
public static void main(String[] args){
Scanner read = new Scanner(System.in);
n = read.nextInt();
for(int i = 0;i < n;i++){
for(int j = 0;j < n;j++){
path[i][j] = ".";
}
}
dfs(0);
}
public static void dfs(int k){
if(k == n){
for(int i = 0;i < n;i++){
for(int j = 0;j < n;j++){
System.out.print(path[i][j]);
}
System.out.println();
}
System.out.println();
return;
}
for(int i = 0;i < n;i++){
if(!col[i] && !diagonal[k+i] && !cdiagonal[i-k+n]){
path[k][i] = "Q";
col[i] = dg[k+i] = udg[i-k+n] = true;
dfs(k+1);
path[k][i] = ".";
col[i] = dg[k+i] = udg[i-k+n] = false;
}
}
}
}
```
**------------恢復內容結束-------