N皇后问题---回溯法

问题描述
在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
N后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后不可以在同一行或同一列或同一斜线上。

输入:
给定棋盘的大小n (n ≤ 13)
输出:
输出有多少种放置方法。

解题思路:
要解决N皇后问题,其实就是要解决好怎么放置这n个皇后,每一个皇后与前面的所有皇后不能在同一行、同一列、同一对角线,在这里我们可以以行优先,就是说皇后的行号按顺序递增,只考虑第i个皇后放置在第i行的哪一列,所以在放置第i个皇后的时候,可以从第1列判断起,如果可以放置在第1个位置,则跳到下一行放置下一个皇后。如果不能,则跳到下一列…直到最后一列,如果最后一列也不能放置,则说明此时放置方法出错,则回到上一个皇后向之前放置的下一列重新放置。此即是回溯法的精髓所在。当第n个皇后放置成功后,即得到一个可行解,此时再回到上一个皇后重新放置寻找下一个可行解…如此后,即可找出一个n皇后问题的所有可行解。

//n皇后 回溯法 这里是将数组x模拟为二维数组,这里的列不会重复,只需要判定行和对角线是否会重复
class Queen
{
    friend int Nqueen(int n);//该类的友元函数
private:
//x[m]=n表示从第m列的从上往下数第n个元素,这个很重要,将一维的变为二维
    bool Place(int k)//该函数用来判断该皇后是否处于合适位置
    {
        for (int i = 0; i < k; ++i)
        {
            if ( (x[i] == x[k]) || (abs(x[i] - x[k]) == abs(i - k)))//如果插入的元素和之前已插入元素在同一行或者同一列,则不能插入,返回false
            {
                return false;
            }
        }
        return true;
    }
    void Backtrack(int i)
    {
        if (i == n)
        {
            for (int r = 0; r < n;++r)
            {
                for (int c = 0; c < n;++c)//按行打印
                {
                    if (x[c] == r)
                    {
                        cout << "Q" << " ";
                    }
                    else
                    {
                        cout << "#"<<" ";
                    }
                }
                cout << endl;
            }
            cout << endl;
            sum += 1;
        }
        else
        {
        //j=0 x[0],x[1],x[2],x[3]=0;每一列的第一行
            for (int j = 0; j < n; ++j)
            {
                x[i] = j;//按列放入
                if (Place(i))
                {
                    Backtrack(i+1);
                }
            }
        }
    }

    int n;//n后问题
    int *x;//数组名
    int sum;//皇后最多几种摆放
};
int Nqueen(int n)
{
    Queen Q;
    Q.n = n;
    Q.sum = 0;
    Q.x = new int[n];
    for (int i = 0; i < n; ++i) Q.x[i] = 0;//数组全置为0
    Q.Backtrack(0);//从第0列开始
    delete[]Q.x;
    return Q.sum;
}
void main()
{
    int sum;
    int n;
    cin >> n;
    sum = Nqueen(n);
    cout <<"皇后最多种摆放个数" <<" "<<sum<< endl;
}

《N皇后问题---回溯法》

    原文作者:回溯法
    原文地址: https://blog.csdn.net/qq_25123049/article/details/52184411
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞