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;
}

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章