
- 資料結構與演算法
- DSA - 首頁
- DSA - 概述
- DSA - 環境搭建
- DSA - 演算法基礎
- DSA - 漸近分析
- 資料結構
- DSA - 資料結構基礎
- DSA - 資料結構和型別
- DSA - 陣列資料結構
- 連結串列
- DSA - 連結串列資料結構
- DSA - 雙向連結串列資料結構
- DSA - 迴圈連結串列資料結構
- 棧與佇列
- DSA - 棧資料結構
- DSA - 表示式解析
- DSA - 佇列資料結構
- 搜尋演算法
- DSA - 搜尋演算法
- DSA - 線性搜尋演算法
- DSA - 二分搜尋演算法
- DSA - 插值搜尋
- DSA - 跳躍搜尋演算法
- DSA - 指數搜尋
- DSA - 斐波那契搜尋
- DSA - 子列表搜尋
- DSA - 雜湊表
- 排序演算法
- DSA - 排序演算法
- DSA - 氣泡排序演算法
- DSA - 插入排序演算法
- DSA - 選擇排序演算法
- DSA - 歸併排序演算法
- DSA - 希爾排序演算法
- DSA - 堆排序
- DSA - 桶排序演算法
- DSA - 計數排序演算法
- DSA - 基數排序演算法
- DSA - 快速排序演算法
- 圖資料結構
- DSA - 圖資料結構
- DSA - 深度優先遍歷
- DSA - 廣度優先遍歷
- DSA - 生成樹
- 樹資料結構
- DSA - 樹資料結構
- DSA - 樹的遍歷
- DSA - 二叉搜尋樹
- DSA - AVL 樹
- DSA - 紅黑樹
- DSA - B 樹
- DSA - B+ 樹
- DSA - 伸展樹
- DSA - Trie 樹
- DSA - 堆資料結構
- 遞迴
- DSA - 遞迴演算法
- DSA - 使用遞迴實現漢諾塔
- DSA - 使用遞迴實現斐波那契數列
- 分治法
- DSA - 分治法
- DSA - 最大最小問題
- DSA - Strassen 矩陣乘法
- DSA - Karatsuba 演算法
- 貪心演算法
- DSA - 貪心演算法
- DSA - 旅行商問題(貪心法)
- DSA - Prim 最小生成樹
- DSA - Kruskal 最小生成樹
- DSA - Dijkstra 最短路徑演算法
- DSA - 地圖著色演算法
- DSA - 分數揹包問題
- DSA - 帶截止日期的作業排序
- DSA - 最優合併模式演算法
- 動態規劃
- DSA - 動態規劃
- DSA - 矩陣鏈乘法
- DSA - Floyd-Warshall 演算法
- DSA - 0-1 揹包問題
- DSA - 最長公共子序列演算法
- DSA - 旅行商問題(動態規劃法)
- 近似演算法
- DSA - 近似演算法
- DSA - 頂點覆蓋演算法
- DSA - 集合覆蓋問題
- DSA - 旅行商問題(近似演算法)
- 隨機化演算法
- DSA - 隨機化演算法
- DSA - 隨機化快速排序演算法
- DSA - Karger 最小割演算法
- DSA - Fisher-Yates 洗牌演算法
- DSA 有用資源
- DSA - 問答
- DSA - 快速指南
- DSA - 有用資源
- DSA - 討論
N 皇后問題
什麼是 N 皇后問題?
在N 皇后問題中,我們給定一個NxN的棋盤,我們必須在棋盤上放置N個皇后,使得任何兩個皇后都不互相攻擊。如果皇后位於其路徑上的水平、垂直或對角線上,則一個皇后將攻擊另一個皇后。解決 N 皇后難題最流行的方法是回溯法。
輸入輸出場景
假設給定的棋盤大小為 4x4,我們必須在其中排列正好 4 個皇后。解決方案排列如下圖所示:

最終的解決方案矩陣將是:
0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0
解決 N 皇后問題的回溯法
在解決 N 皇后問題的樸素方法中,演算法會生成所有可能的解決方案。然後,它逐一探索所有解決方案。如果生成的解決方案滿足問題的約束條件,則列印該解決方案。
按照以下步驟使用回溯法解決 N 皇后問題:
將第一個皇后放在棋盤的左上角單元格中。
將皇后放在第一個單元格後,將該位置標記為解決方案的一部分,然後遞迴檢查這是否會導致解決方案。
現在,如果放置皇后不會導致解決方案,則返回第一步,並將皇后放置在其他單元格中。重複此過程,直到嘗試完所有單元格。
如果放置皇后返回導致解決方案,則返回 TRUE。
如果所有皇后都已放置,則返回 TRUE。
如果嘗試完所有行但未找到解決方案,則返回 FALSE。
示例
以下示例說明如何在各種程式語言中使用 5 個皇后解決 N 皇后問題。
#include<stdio.h> #define BOARD_SIZE 5 void displayChess(int chBoard[BOARD_SIZE][BOARD_SIZE]) { for (int row = 0; row < BOARD_SIZE; row++) { for (int col = 0; col < BOARD_SIZE; col++) printf("%d ", chBoard[row][col]); printf("\n"); } } int isQueenPlaceValid(int chBoard[BOARD_SIZE][BOARD_SIZE], int crntRow, int crntCol) { // checking if queen is in the left or not for (int i = 0; i < crntCol; i++) if (chBoard[crntRow][i]) return 0; for (int i = crntRow, j = crntCol; i >= 0 && j >= 0; i--, j--) //checking if queen is in the left upper diagonal or not if (chBoard[i][j]) return 0; for (int i = crntRow, j = crntCol; j >= 0 && i < BOARD_SIZE; i++, j--) //checking if queen is in the left lower diagonal or not if (chBoard[i][j]) return 0; return 1; } int solveProblem(int chBoard[BOARD_SIZE][BOARD_SIZE], int crntCol) { //when N queens are placed successfully if (crntCol >= BOARD_SIZE) return 1; // checking placement of queen is possible or not for (int i = 0; i < BOARD_SIZE; i++) { if (isQueenPlaceValid(chBoard, i, crntCol)) { //if validate, place the queen at place (i, col) chBoard[i][crntCol] = 1; //Go for the other columns recursively if (solveProblem(chBoard, crntCol + 1)) return 1; //When no place is vacant remove that queen chBoard[i][crntCol] = 0; } } return 0; } int displaySolution() { int chBoard[BOARD_SIZE][BOARD_SIZE]; for(int i = 0; i < BOARD_SIZE; i++) for(int j = 0; j < BOARD_SIZE; j++) //set all elements to 0 chBoard[i][j] = 0; //starting from 0th column if (solveProblem(chBoard, 0) == 0) { printf("Solution does not exist"); return 0; } displayChess(chBoard); return 1; } int main() { displaySolution(); return 0; }
#include<iostream> using namespace std; #define BOARD_SIZE 5 void displayChess(int chBoard[BOARD_SIZE][BOARD_SIZE]) { for (int row = 0; row < BOARD_SIZE; row++) { for (int col = 0; col < BOARD_SIZE; col++) cout << chBoard[row][col] << " "; cout << endl; } } bool isQueenPlaceValid(int chBoard[BOARD_SIZE][BOARD_SIZE], int crntRow, int crntCol) { // checking if queen is in the left or not for (int i = 0; i < crntCol; i++) if (chBoard[crntRow][i]) return false; for (int i = crntRow, j = crntCol; i >= 0 && j >= 0; i--, j--) //checking if queen is in the left upper diagonal or not if (chBoard[i][j]) return false; for (int i = crntRow, j = crntCol; j >= 0 && i < BOARD_SIZE; i++, j--) //checking if queen is in the left lower diagonal or not if (chBoard[i][j]) return false; return true; } bool solveProblem(int chBoard[BOARD_SIZE][BOARD_SIZE], int crntCol) { //when N queens are placed successfully if (crntCol >= BOARD_SIZE) return true; // checking placement of queen is possible or not for (int i = 0; i < BOARD_SIZE; i++) { if (isQueenPlaceValid(chBoard, i, crntCol)) { //if validate, place the queen at place (i, col) chBoard[i][crntCol] = 1; //Go for the other columns recursively if (solveProblem(chBoard, crntCol + 1)) return true; //When no place is vacant remove that queen chBoard[i][crntCol] = 0; } } return false; } bool displaySolution() { int chBoard[BOARD_SIZE][BOARD_SIZE]; for(int i = 0; i < BOARD_SIZE; i++) for(int j = 0; j < BOARD_SIZE; j++) //set all elements to 0 chBoard[i][j] = 0; //starting from 0th column if (solveProblem(chBoard, 0) == false) { cout << "Solution does not exist"; return false; } displayChess(chBoard); return true; } int main() { displaySolution(); }
public class Main { static final int BOARD_SIZE = 5; static void displayChess(int chBoard[][]) { for (int row = 0; row < BOARD_SIZE; row++) { for (int col = 0; col < BOARD_SIZE; col++) System.out.print(chBoard[row][col] + " "); System.out.println(); } } static boolean isQueenPlaceValid(int chBoard[][], int crntRow, int crntCol) { // checking if queen is in the left or not for (int i = 0; i < crntCol; i++) if (chBoard[crntRow][i] == 1) return false; for (int i = crntRow, j = crntCol; i >= 0 && j >= 0; i--, j--) //checking if queen is in the left upper diagonal or not if (chBoard[i][j] == 1) return false; for (int i = crntRow, j = crntCol; j >= 0 && i < BOARD_SIZE; i++, j--) //checking if queen is in the left lower diagonal or not if (chBoard[i][j] == 1) return false; return true; } static boolean solveProblem(int chBoard[][], int crntCol) { //when N queens are placed successfully if (crntCol >= BOARD_SIZE) return true; // checking placement of queen is possible or not for (int i = 0; i < BOARD_SIZE; i++) { if (isQueenPlaceValid(chBoard, i, crntCol)) { //if validate, place the queen at place (i, col) chBoard[i][crntCol] = 1; //Go for the other columns recursively if (solveProblem(chBoard, crntCol + 1)) return true; //When no place is vacant remove that queen chBoard[i][crntCol] = 0; } } return false; } static boolean displaySolution() { int chBoard[][] = new int[BOARD_SIZE][BOARD_SIZE]; for(int i = 0; i < BOARD_SIZE; i++) for(int j = 0; j < BOARD_SIZE; j++) //set all elements to 0 chBoard[i][j] = 0; //starting from 0th column if (!solveProblem(chBoard, 0)) { System.out.println("Solution does not exist"); return false; } displayChess(chBoard); return true; } public static void main(String[] args) { displaySolution(); } }
BOARD_SIZE = 5 def displayChess(chBoard): for row in range(BOARD_SIZE): for col in range(BOARD_SIZE): print(chBoard[row][col], end=" ") print() def isQueenPlaceValid(chBoard, crntRow, crntCol): # checking if queen is in the left or not for i in range(crntCol): if chBoard[crntRow][i]: return False for i, j in zip(range(crntRow, -1, -1), range(crntCol, -1, -1)): #checking if queen is in the left upper diagonal or not if chBoard[i][j]: return False for i, j in zip(range(crntRow, BOARD_SIZE), range(crntCol, -1, -1)): #checking if queen is in the left lower diagonal or not if chBoard[i][j]: return False return True def solveProblem(chBoard, crntCol): #when N queens are placed successfully if crntCol >= BOARD_SIZE: return True # checking placement of queen is possible or not for i in range(BOARD_SIZE): if isQueenPlaceValid(chBoard, i, crntCol): #if validate, place the queen at place (i, col) chBoard[i][crntCol] = 1 #Go for the other columns recursively if solveProblem(chBoard, crntCol + 1): return True #When no place is vacant remove that queen chBoard[i][crntCol] = 0 return False def displaySolution(): chBoard = [[0 for _ in range(BOARD_SIZE)] for _ in range(BOARD_SIZE)] #starting from 0th column if not solveProblem(chBoard, 0): print("Solution does not exist") return False displayChess(chBoard) return True if __name__ == "__main__": displaySolution()
輸出
1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0
廣告