n皇后

// n皇后.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <conio.h>
#define MAX 32


void ShowResult(int data[][32], int n)
{
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            printf("%2d", data[i][j]);
        }
        printf("/n");
    }
    printf("/n");
}

bool IsCurrentPosFeasible(int data[][32], int line, int row, int n)
{
    bool bReturn;

    for (int i = 0; i < n; ++i)
    {
        if ((1 == data[line][i]) || (1 == data[i][row]))
        {
            return false;
        }
    }

    for (int i = 0; i < line; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            bReturn = ((i + j == line + row || i - j == line - row) && (1 == data[i][j]));
            if (true == bReturn)
            {
                return false;
            }
        }
    }

    return true;
}


void NQueen(int data[][32], int line, int n)
{
    if (line > n - 1)
    {
        ShowResult(data, n);
        getch();

        return ;
    }
    for (int i = 0; i < n; ++i)
    {
        if (IsCurrentPosFeasible(data, line, i, n))
        {
            data [line][i] = 1;
            NQueen(data, line + 1, n);
            data[line][i] = 0;
        }
    }
}


int _tmain(int argc, _TCHAR* argv[])
{
    int data[MAX][MAX] = {0};

    NQueen(data, 0, 25);

    return 0;
}

### N皇后问题的解决方案 N皇后问题是计算机科学中的经典问题之一,其目标是将N个皇后放置在N×N的棋盘上,使得它们彼此之间不会互相攻击。这意味着任何两个皇后都不能位于同一行、同一列或同一条对角线。 #### 算法原理 该问题通常采用回溯算法来解决。回溯是一种试探性的搜索技术,在逐步构建候选解的过程中尝试每一步可能的选择,并在发现当前路径无法得到合法解时撤销最近一次选择并继续其他可能性[^1]。 具体来说,对于每一行,我们依次尝试将一个皇后放在不同的列位置上,并验证这个位置是否与其他已放置皇后的行列以及两条主要方向上的对角线冲突。如果没有冲突,则递归处理下一行;如果发生冲突或者已经到达最后一行,则返回到前一层重新调整布局。 #### 实现细节 以下是基于上述思路的一个Java实现例子: ```java public class NQueens { public static void solveNQueens(int n) { int[] board = new int[n]; // 存储第i行皇后所在的列号 Arrays.fill(board, -1); boolean[] colFree = new boolean[n]; Arrays.fill(colFree, true); // 列可用状态数组初始化为true表示全自由 // 主副对角线标记数组长度应设为2*n-1因为最大差值范围[-(n-1), (n-1)] boolean[] mainDiagFree = new boolean[2 * n - 1]; boolean[] antiDiagFree = new boolean[2 * n - 1]; Arrays.fill(mainDiagFree, true); Arrays.fill(antiDiagFree, true); placeQueen(n, 0, board, colFree, mainDiagFree, antiDiagFree); } private static void placeQueen(int n, int row, int[] board, boolean[] colFree, boolean[] mainDiagFree, boolean[] antiDiagFree){ if(row == n){ // 找到了一种摆放方式 printBoard(board); return; } for(int col=0;col<n;col++){ if(colFree[col] && mainDiagFree[row-col+n-1] && antiDiagFree[row+col]){ board[row]=col; colFree[col]=false; mainDiagFree[row-col+n-1]=false; antiDiagFree[row+col]=false; placeQueen(n,row+1,board,colFree,mainDiagFree,antiDiagFree); // 回退操作恢复现场以便探索更多情况 colFree[col]=true; mainDiagFree[row-col+n-1]=true; antiDiagFree[row+col]=true; board[row]=-1;//清除当前位置记录 }//end if safe condition met }//end loop over columns at current row }//end method place queen recursive function definition private static void printBoard(int[] board){ System.out.println("Solution found:"); for(int i : board){ char[] line=new char[board.length]; Arrays.fill(line,&#39;.&#39;); if(i!=-1)//only when there is a valid column index set by previous steps do we mark it with &#39;Q&#39; line[i]=&#39;Q&#39;; System.out.println(new String(line)); } System.out.println(); } }//end class declaration ``` 此代码定义了一个`solveNQueens`函数用于启动整个求解过程,并通过辅助函数`placeQueen`完成实际的递归调用和条件判断逻辑。最终打印出所有找到的有效配置方案[^2]。 #### 总结 综上所述,利用回溯策略可以有效地枚举所有的可行排列组合从而找出满足约束条件的所有解答。这种方法虽然简单易懂但也存在效率低下等问题特别是当规模较大时运行时间会显著增加因此还需要考虑优化措施比如剪枝提前终止不必要的分支扩展等手段提升性能表现[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值