問題描述:八皇后問題是乙個以西洋棋為背景的問題:如何能夠在8×8的西洋棋棋盤上放置八個皇后, 使得任何乙個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行、縱行或斜線上,此問題進而可以推廣為n皇后的問題。
解題思路:n*n的矩陣,遞迴每乙個點,當皇后數量達到n的時候,進行判斷,若滿足題目條件,則答案加一(number++),否則繼續進行遍歷。
儲存皇后點的方法:構造乙個二維陣列reserve,當reserve[i][j] == 1時候,則該點已經有皇后,若reserve[i][j]==0則,皇后可以存在於該點,且該點置為一。
判斷皇后數量的方法,定義乙個int sign ,當sign<8的時候遞迴遍歷,並且重複上一操作,否則對reserve陣列進行判斷,判斷此陣列內等於1的點的座標,是否滿足題意,判斷完之後,當前點置為0.
判斷x,y軸只需要判斷是否有相等的座標值即可。
判斷斜線,則判斷每兩個點之間座標值相減的絕對值是否相等,(這裡需要遞迴遍歷每乙個點)若相等,則點在斜線上重複,返回false,若不相等,則點在斜線上不重複,返回true。
先定義全域性變數:
private static int number = 0; //表示答案數量int count = 0; //下文的陣列下標
static string str ; //儲存正確答案的字串陣列,為了去除重複
定義主函式:
public static void main(string args)
下面執行遍歷操作的函式:
public void startrun(int reserve , int n ,int sign)if(sign == n)
}else if(sign < n)
reserve[i][j] = 0;
}} }
下面對陣列reserve進行皇后位置判斷:
/** 檢查兩個皇后是否在同一行,同一列,或者同一斜線上
* 存在返回false
* 不存在返回true
*/public boolean checkallquean(int reserve , int n)
}}// 獲得所有皇后的點座標
for(x1 = 0;x1 < n;x1++)
}} if(!checkrenumber(x,y,n))
return true;
}
刪除重複答案的函式:
/** 將確定的解答陣列,儲存在乙個string裡面,用來避免重複
* 若重複則返回false
* 不重複則返回true
*/public boolean checkrenumber(int x,int y , int n)
for(string st : str)
} str[count++] = test;
return true;
}
下面進行對兩個皇后位置的判斷:
/** 檢查兩個皇后是否在同一行,同一列,或者同一斜線上
* 存在返回false
* 不存在返回true
*/public boolean checktwoquean(int i , int j , int m ,int n)
}
下面是輸出reserve點的函式:
public void output(int reserve , int n)} }
完,但是效率極低,非常低。
輸出案例:
請輸入皇后數字n:40,1 1,3 2,0 3,2
0,2 1,0 2,3 3,1
2
n皇后問題在大於等於4的時候有解
經典遞迴 N皇后問題
用來存放皇后,轉換為二維矩陣,元素座標為 i,q i int n 4 void nqueen int k int main void nqueen int k for int i 0 i n i if j k 首先盯著第二個 for loop 看 for int i 0 i n i 函式的遞迴發生在...
遞迴經典問題 N皇后問題
n皇后問題是指在乙個n n的西洋棋棋盤上,有n個棋子,這n個棋子均不在同一行,同一列,同一對角線上,請問一共有幾種排列方式?因為每列都要有棋子,所以只要把每一列的棋子所在的行數排下來就行了,比如第一列到第五列棋子所在的行數依次是24135,然後只要檢視每種方法是否滿足要求就行了。void gener...
八皇后 N皇后問題 遞迴實現
八皇后問題,即在乙個棋盤上,每行都可以放置乙個皇后,但每個皇后都不能影響其他皇后的安全,即所有皇后的位置不能在同一直線上 解決問題方法及思想 遞迴 在使用遞迴之前首先要準備好兩個函式實現 1.判斷此時此刻位置是否安全 只需要判斷元素上方,左上方,右上方是否安全,且只要有乙個位置不安全,則結束判斷 2...