八皇后問題的三種解法

2021-08-21 21:00:28 字數 2426 閱讀 6832

會下西洋棋的人都很清楚:皇后可以在橫、豎、斜線上不限步數地吃掉其他棋子。如何將8個皇后放在棋盤上(有8 * 8個方格),使它們誰也不能被吃掉!這就是著名的八皇后問題。 對於某個滿足要求的8皇后的擺放方法,定義乙個皇后串a與之對應,即a=b1b2…b8,其中bi為相應擺法中第i行皇后所處的列數。已經知道8皇后問題一共有92組解(即92個不同的皇后串)。給出乙個數b,要求輸出第b個串。串的比較是這樣的:皇后串x置於皇后串y之前,當且僅當將x視為整數時比y小。 

輸入資料

第1行是測試資料的組數n,後面跟著n行輸入。每組測試資料佔1行,包括乙個正整數b(1 <= b <= 92)

輸出要求

n行,每行輸出對應乙個輸入。輸出應是乙個正整數,是對應於b的皇后串

輸入樣例21

92輸出樣例

15863724

84136275

因為要求出92種不同擺放方法中的任意一種,所以我們不妨把92種不同的擺放方法一次性求出來,存放在乙個陣列裡。為求解這道題我們需要有乙個矩陣**棋盤,每次試放乙個棋子時只能放在尚未被控制的格仔上,一旦放置了乙個新棋子,就在它所能控制的所有位置上設定標記,如此下去把八個棋子放好。當完成一種擺放時,就要嘗試下一種。若要按照字典序將可行的擺放方法記錄下來,就要按照一定的順序進行嘗試。也就是將第乙個棋子按照從小到大的順序嘗試;對於第乙個棋子的每乙個位置,將第二個棋子從可行的位置從小到大的順序嘗試;在第一第二個棋子固定的情況下,將第三個棋子從可行的位置從小到大的順序嘗試;依次類推。

首先,我們有乙個8*8的矩陣**棋盤標識當前已經擺放好的棋子所控制的區域。用乙個有92行每行8個元素的二維陣列記錄可行的擺放方法。用乙個遞迴程式來實現嘗試擺放的過程。基本思想是假設我們將第乙個棋子擺好,並設定了它所控制的區域,則這個問題變成了乙個7皇后問題,用與8皇后同樣的方法可以獲得問題的解。那我們就把重心放在如何擺放乙個皇后棋子上,擺放的基本步驟是:從第1到第8個位置,順序地嘗試將棋子放置在每乙個未被控制的位置上,設定該棋子所控制的格仔,將問題變為更小規模的問題向下遞迴,需要注意的是每次嘗試乙個新的未被控制的位置前,要將上一次嘗試的位置所控制的格仔復原。

[cpp]view plain

copy

#include 

#include 

int queenplaces[92][8]; //存放92種皇后棋子的擺放方法  

int count = 0;  

int board[8][8]; //**棋盤  

void putqueen(int ithqueen); //遞迴函式,每次擺好乙個棋子  

void main()  

putqueen(0); //從第0個棋子開始擺放,執行的結果是將queenplaces生成好  

scanf(」%d」, &n);  

for(i = 0; i < n; i++)  

}  void putqueen(int ithqueen)  

for(i = 0; i < 8; i++)  

}  }  

上面的方法用乙個二維陣列來記錄棋盤被已經放置的棋子的控制情況,每次有新的棋子放置時用了列舉法來判斷它控制的範圍。還可以用三個一維陣列來分別記錄每一列,每個45度的斜線和每個135度的斜線上是否已經被已放置的棋子控制,這樣每次有新的棋子放置時,不必再搜尋它的控制範圍,可以直接通過三個一維陣列判斷它是否與已經放置的棋子衝突,在不衝突的情況下,也可以通過分別設定三個一維陣列的相應的值,來記錄新棋子的控制範圍。

#include int  record[92][9], mark[9], count = 0; //record記錄全部解,mark記錄當前解;

bool range[9], line1[17], line2[17]; //分別記錄列方向,45度,135度方向上被控制的情況

void trytoput(int ); //求全部解的過程

void main()

}void trytoput(int i)

for(int j=1; j<=8; j++)

}}

這個題目也可以不用**棋盤來模擬已放置棋子的控制區域,而只用乙個有8個元素的陣列記錄已經擺放的棋子擺在什麼位置,當要放置乙個新的棋子時,只需要判斷它與已經放置的棋子之間是否衝突就行了。

#include int ans[92][8], n, b, i, j, num, hang[8];

void queen(int i)

for (j=0; j<8; j++){ //將當前皇后i逐一嘗試放置在不同的列

for(k=0; k問題一: 使用列舉法,窮舉8個皇后的所有可能位置組合,逐一判斷是否可以互相被吃掉,得到超時錯誤;

問題二:對於多組輸入,有多組輸出,沒有在每組輸出後加換行符,得到格式錯;

問題三:對輸入輸出的函式不熟悉,試圖將數字轉換成字元或者將8個整數轉換成8位的十進位制整數來完成輸出,形成不必要的冗餘**。

python八皇后問題2種解法

八皇后問題 思路 確保每乙個皇后的左上角 右上角或正上方沒有皇后,用這個規則遞迴地每一行,再每一列迴圈過去,每一列或每一行只有乙個元素 from tkinter import from pil import image,imagetk size 8class eightqueen def init ...

八皇后問題的兩種解法

八皇后問題,是回溯演算法 的典型案例。該問題是國際西洋棋棋手馬克斯 貝瑟爾於1848年提出 在8x8格的西洋棋 上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行 同一列或同一斜線上,問有多少種擺法。高斯認為有76種方案。1854年在柏林 的象棋雜誌上不同的作者發表了40種不同的解,後...

八皇后的92種解法

package com.recursion.implementation public class eightqueen 方法,放置第n個皇后 第一行第一列的方法為 1 8 7 private void check int n 如果沒有到最後則依次放入 for int i 0 i max i 如果衝...