C++ 用一維數組加遞歸完成八皇后至N皇后的解答

先上代碼,其中是用p[0]來存儲當前符合的次數,基本思路就是一行一行尋找合適的位子,若本行沒有則返回上一行,在上一行查找合適的位子。相對於用循環,遞歸的整體代碼思路更清晰。

//檢查當前行上的皇后位子是否合理,是返回true
bool Check(vector<int>&p,int line)
{
    //當前行與前幾行的皇后位子進行規則比較,判斷當前行皇后位子是否合理
    for(int i = 1;i < line;i++)
    {
        //在同一列或在對角線上,返回false
        if(p.at(line) == p.at(i) || abs(p.at(i) - p.at(line)) == abs(i-line))
            return false;
    }
    return true;
}
void QueesRun(vector<int>&p,int line,int length)
{
    p.at(line) = 1;//每行皇后初始位子都是從第一個開始
    for(int i=1;i<=length;i++)
    {
        if(Check(p,line))
        {
            if(line == length)//如果已經到最底行,並且每行都滿足,則加一
                p.at(0) ++;
            else//進行下一行皇后選位
                QueesRun(p,line + 1,length);
        }
        if(p.at(line) == length)//當前行位子已經全部試過,則將上一行皇后位子進行重新尋找
            return ;
        p.at(line) ++;//當前行皇后的位子進行加
    }
}

int main(int argc, char const *argv[])
{
    vector<int> p;
    p.resize(9,0);    //9可以更改成其他數字N+1,就爲N皇后了
    QueesRun(p,1,p.size() - 1);
    cout << "總共有:" << p.at(0) << endl;
    return 0;
}

運行結果

借用一下百度百科對八皇后問題的描述:https://baike.baidu.com/item/%E5%85%AB%E7%9A%87%E5%90%8E%E9%97%AE%E9%A2%98/11053477?fromtitle=%E5%85%AB%E7%9A%87%E5%90%8E&fromid=10742426&fr=aladdin

八皇后問題,是一個古老而著名的問題,是回溯算法的典型案例。該問題是國際西洋棋棋手馬克斯·貝瑟爾於1848年提出:在8×8格的國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法。 高斯認爲有76種方案。1854年在柏林的象棋雜誌上不同的作者發表了40種不同的解,後來有人用圖論的方法解出92種結果。計算機發明後,有多種計算機語言可以解決此問題。

思路:

1.首先考慮用什麼方法去完成,這裏是用一維數組加遞歸,原本是打算用循環的,寫着寫着發現那樣太囉嗦了,就換成遞歸了

2.位子的合理性判斷,即上面代碼Check()函數的實現,檢查當前行與之前行的皇后是否在攻擊範圍,不在,則返回true;

3.對每一行的皇后位子進行遍歷,尋找合適位子安放皇后,如果當前行的皇后安放位置滿足條件,則進入下一行。

4.當全部行都滿足的時候,p[0]++;然後return再次尋找合適位子。以此往復,便可以找出所有解了。

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