N皇后问题

问题描述

在一个 N X N 的国际象棋棋盘上,放置 N 个皇后,使得任何两个皇后之间都不能互相攻击。皇后在国际象棋中能够水平、垂直以及对角线方向上攻击其他棋子,因此放置的 N 个皇后必须满足:在同一行、同一列以及同一条对角线上不能有两个皇后。

1. 问题理解:

    •    输入:一个整数 N,代表棋盘大小和皇后数量。
    •    输出:所有满足条件的皇后放置方案,或方案数量。

代码: 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

#define N 5  // 可以更改 N 的值来解决不同大小的皇后问题
int count = 0;

void printBoard(int board[N][N]);

// 函数来检查是否可以在 board[row][col] 放置皇后
int isSafe(int board[N][N], int row, int col) {
    int i, j;

    // 检查同一列
    for (i = 0; i < row; i++)
        if (board[i][col] == 1)
            return 0;

    // 检查左上对角线
    for (i = row, j = col; i >= 0 && j >= 0; i--, j--)
        if (board[i][j] == 1)
            return 0;
    
    // 检查右上对角线
    for (i = row, j = col; i >= 0 && j < N; i--, j++)
        if (board[i][j] == 1)
            return 0;
    /*
        举例:最开始row=0   由solveNQUtil函数可知:
        board[0][0]可以放皇后  然后solveNQUtil(board, row + 1, solutions)递归
        此时row=1 ,进入新的solveNQUtil函数,for循环中col=0开始++ 若borad[0][0]=1 同一列不可以放皇后即board[1][0]不可以放皇后
        col+1=1,又因为board[1][1]=1所以board[1][1]不可以放皇后....
    
    */
 
    
    return 1;
}

// 函数来解决 N 皇后问题
void solveNQUtil(int board[N][N], int row, int& solutions) {
    // 如果所有皇后都放置完成
    if (row >= N) {
        solutions++;
        printBoard(board);
        return;  //程序结束
    }

    // 在当前行尝试放置皇后并递归地放置剩下的皇后
    for (int col = 0; col < N; col++) {
        // 检查放置皇后的位置是否安全
        if (isSafe(board, row, col)) {
            board[row][col] = 1;  // 放置皇后
            solveNQUtil(board, row + 1, solutions);  // 递归放置下一个皇后
            board[row][col] = 0;  // 回溯   把皇后位置重新变为0
        }
    }
}

// 打印棋盘函数
void printBoard(int board[N][N]) {
    printf("Solution %d:\n", ++count);
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++)
            printf("%d ", board[i][j]);
        printf("\n");
    }
    printf("\n");
}

// 用于解决 N 皇后问题的主函数
void solveNQ() {
    int board[N][N] = { 0 };  // 初始化棋盘
    int solutions = 0;
    solveNQUtil(board, 0, solutions);

    printf("Total number of solutions are %d\n", solutions);
}

// 主函数
int main() {
    solveNQ();
    return 0;
}

运行结果: 

84f8a2a8481b452d9b9bda9a76d29ebd.png

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值