回溯法解决n皇后

20 阅读1分钟

#include <stdio.h>
#include <stdbool.h>
 
#define N 8  // 定义棋盘的大小,N为皇后的数量
 
// 函数声明
void solveNQueens(int board[N][N], int row);
bool isSafe(int board[N][N], int row, int col);
void printSolution(int board[N][N]);
 
// 主函数
int main() {
    int board[N][N] = {0};  // 初始化棋盘,0表示空位,1表示放置皇后
 
    // 开始解决N皇后问题
    solveNQueens(board, 0);
 
    return 0;
}
 
// 解决N皇后问题的函数
void solveNQueens(int board[N][N], int row) {
    // 如果所有的皇后都被放置了,打印解决方案
    if (row == N) {
        printSolution(board);
        return;
    }
 
    // 遍历当前行的每一列
    for (int col = 0; col < N; col++) {
        // 检查当前列和对角线是否安全
        if (isSafe(board, row, col)) {
            board[row][col] = 1;  // 放置皇后
 
            // 递归调用,尝试放置下一个皇后
            solveNQueens(board, row + 1);
 
            // 回溯,移除皇后,尝试下一个列位置
            board[row][col] = 0;
        }
    }
}
 
// 检查当前位置是否安全的函数
bool isSafe(int board[N][N], int row, int col) {
    // 检查当前列是否有其他皇后
    for (int i = 0; i < row; i++) {
        if (board[i][col] == 1) {
            return false;  // 列冲突
        }
    }
 
    // 检查主对角线(左上到右下)是否有其他皇后
    for (int i = row, j = col; i >= 0 && j >= 0; i--, j--) {
        if (board[i][j] == 1) {
            return false;  // 主对角线冲突
        }
    }
 
    // 检查副对角线(右上到左下)是否有其他皇后
    for (int i = row, j = col; i >= 0 && j < N; i--, j++) {
        if (board[i][j] == 1) {
            return false;  // 副对角线冲突
        }
    }
 
    return true;  // 当前位置安全
}
 
// 打印棋盘的解决方案
void printSolution(int board[N][N]) {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            printf(" %d ", board[i][j]);  // 打印棋盘上每个位置的值
        }
        printf("\n");
    }
    printf("\n");  // 打印解决方案之间的分隔
}