N皇后问题(自学版)

写在前面:

        刚刚在数据结构与算法面试题上面看到了有关这个“N皇后”的东东,想着来学学看看。

什么是N皇后问题?

题目如下:

        在n*n的方格棋盘上,放置n个皇后,要求每个皇后不同行、不同列、不同对角线。

        回溯思路:

  • 从第0行开始,逐行放置皇后。
  • 对于当前行,尝试放置在每一列。
  • 每放置一个皇后,都要检查当前位置是否与之前放置的皇后位置冲突:
    • 同列冲突:检查当前列是否已经有皇后。
    • 对角线冲突:检查当前位置是否与之前皇后的对角线有冲突。(这两条是区别于深搜的根本因素)
  • 如果找到一个安全的位置放置皇后,则递归地尝试下一行。
  • 如果当前位置无法放置皇后或者递归过程中无法找到解决方案,则回溯到上一步,尝试下一个列位置。

        这题目,理解起来倒不是很难,递归回溯问题(尝试一条路(放置皇后),如果遇到困难(即存在冲突),则返回到上一个状态(就是回溯啦),尝试另一种可能性,直到找到解决方案或者所有可能性都被排除),so???直接上代码吧!!!

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int **board; // 棋盘
int N;       // 棋盘大小
// 打印棋盘
void printBoard() {
    int i, j;
    for (i = 0; i < N; i++) {
        for (j = 0; j < N; j++) {
            printf("%c ", board[i][j] ? 'Q' : '.');
        }
        printf("\n");
    }
    printf("\n");
}
// 检查在board[row][col]位置放置皇后是否符合规则
bool isSafe(int row, int col) {
    int i, j;
    // 检查列是否有皇后冲突
    for (i = 0; i < row; i++) {
        if (board[i][col])
            return false;
    }
    // 检查左上对角线是否有皇后冲突
    for (i = row, j = col; i >= 0 && j >= 0; i--, j--) {
        if (board[i][j])
            return false;
    }
    // 检查右上对角线是否有皇后冲突
    for (i = row, j = col; i >= 0 && j < N; i--, j++) {
        if (board[i][j])
            return false;
    }
    return true;
}
// 递归解决N皇后问题
bool solveNQueens(int row) {
    // 如果已经成功放置了最后一行的皇后,打印棋盘并返回true
    if (row == N) {
        printBoard();
        return true;
    }
    bool res = false;
    int col;
    // 尝试当前行的每一列
    for (col = 0; col < N; col++) {
        // 如果当前位置可以放置皇后
        if (isSafe(row, col)) {
            board[row][col] = 1; // 放置皇后
            // 递归尝试放置下一行的皇后
            res = solveNQueens(row + 1) || res;
            board[row][col] = 0; // 回溯,撤销放置的皇后
        }
    }
    return res;
}
// 主函数,调用求解函数
int main() {
    int i, j;
    // 输入棋盘大小
    printf("Enter the size of the chessboard (N): ");
    scanf("%d", &N);
    if (N <= 0) {
        printf("N must be a positive integer.\n");
        return 1;
    }
    // 动态分配棋盘内存
    board = (int **)malloc(N * sizeof(int *));
    if (board == NULL) {
        printf("Memory allocation failed.\n");
        return 1;
    }
    for (i = 0; i < N; i++) {
        board[i] = (int *)calloc(N, sizeof(int));
        if (board[i] == NULL) {
            printf("Memory allocation failed.\n");
            return 1;
        }
    }
    solveNQueens(0); // 从第0行开始放置皇后
    // 释放棋盘内存
    for (i = 0; i < N; i++) {
        free(board[i]);
    }
    free(board);
    return 0;
}

运行界面:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值