1.八皇后規則簡述
8*8的國際象棋棋盤上擺放8個皇后,要求
1.任意兩個皇后不能處于同一行或同一列
2.任意兩個皇后不能處于同一斜線上
2.解題思路
設滿足提議你的解的兩個皇后的位置為A(x1,y1),B(x2,y2),則根據規則 A和B有關系:
-
x1不等于x2 (不同行)
-
y1不等于y2 (不同列)
-
|x1-x2|不等于|y1-y2|(不處于同一斜線的約束)
由于結果記錄的是8*8棋盤的坐標值,所以結果是二位(x,y)的形式,而由于皇后不能處于同一行,這說明符合條件的8個坐標點一定是 1~8(因為8個皇后都要放置在棋盤上,結果必定是每一行有一個皇后),所以存儲結果的二維數組可以簡化為一維數組,數組的下標對應的就是各個行(x),數組的值就是該皇后放置的列(y);
如 int[0]=1,表示該皇后放在第一行第二列上;
3.解題主要方法
1.獲得結果時打印
public static void resultPrint() {
count++;
for (int i : result) {
System.out.print(i);
}
System.out.println();
}
2.判斷當前結果是否符合
public static boolean charge(int n) {
for (int i = 0; i < n; i++) {
if (result[i] == result[n] //不在同一行,因為用一維數據記錄結果,本來就不在同一行
|| Math.abs(result[i] - result[n]) == Math.abs(n - i)//不在同一斜線上
) {
return false;
}
}
return true;
}
3.放置皇后
public static void check(int n) {
if (n == max) {
//當前如果已經放置到第9行(max==8,從0開始遍歷,當前是第9行),
//說明前8行已經完成放置,則已經得到一種題解
resultPrint();
return;
}
for (int i = 0; i < max; i++) {
//在第n行放置在第i列,然后判斷放置之后的結果是否滿足約束(i范圍0~7)
result[n] = i;
if (charge(n)) {
//當前位置滿足條件,則遞歸放置下一行的皇后
check(n + 1);
}
//如果當前i(列)不滿足,則繼續遍歷下一列嘗試,直至所有列都不可以,則退出
}
}
4.主方法調用
public static void main(String[] args) {
check(0);
System.out.println("總共解法:" + count);
}
5.源碼
public class Queue8 {
public static int max = 8;
public static int count = 0;
public static int[] result = new int[max];
public static void main(String[] args) {
check(0);
System.out.println("總共解法:" + count);
}
public static void check(int n) {
if (n == max) {
//當前如果已經放置到第9行(max==8,從0開始遍歷,當前是第9行),
//說明前8行已經完成放置,則已經得到一種題解
resultPrint();
return;
}
for (int i = 0; i < max; i++) {
//在第n行放置在第i列,然后判斷放置之后的結果是否滿足約束(i范圍0~7)
result[n] = i;
if (charge(n)) {
//當前位置滿足條件,則遞歸放置下一行的皇后
check(n + 1);
}
//如果當前i(列)不滿足,則繼續遍歷下一列嘗試,直至所有列都不可以,則退出
}
}
public static boolean charge(int n) {
for (int i = 0; i < n; i++) {
//不在同一列,因為用一維數據記錄結果,本來就不在同一行
if (result[i] == result[n]
//不在同一斜線上
|| Math.abs(result[i] - result[n]) == Math.abs(n - i)
) {
return false;
}
}
return true;
}
public static void resultPrint() {
count++;
for (int i : result) {
System.out.print(i);
}
System.out.println();
}
}