n皇后问题程序仅适用于n <= 10,即使它应适用于所有n

n-皇后区问题询问有多少种不同的方法可以将n个皇后区放置在n-n-n棋盘上,以使皇后区不能一move而就。我写了一个程序,部分解决了这个问题。我之所以说部分原因是因为我的程序仅适用于n

例如,我的代码输出8 x 8的92个解决方案,9 x 9的352和10 x 10的724输出。这些是n皇后维基百科页面上所述的期望值。但是,我的代码输出11649的1649。预期的答案是2,680。

我真的不知道为什么会这样。

using namespace std;

class Board{
    struct Position{
        int r;
        int c;
    };

    public:
    int size;
    vector<vector<int> > b;         
    Position pos;               
    vector<int> placements;     
    int count;                      

    Board(int s){
        size=s;
        pos.r=0;
        pos.c=0;
        for(int i=0; i<s; i++){
            b.push_back(vector<int>());
            for(int j=0; j<s; j++){
                b.at(i).push_back(0);
            }
        }
        count=0;
    }

    bool hasQueens(){
        for(int i=0; size-i>=0; i++){
            if(b[pos.r][pos.c-i]==1){
                return true;
            }

            if(pos.r-i >= 0){
                if(b[pos.r-i][pos.c-i]==1){
                    return true;
                }
            }

            if(pos.r+i < size){
                if(b[pos.r+i][pos.c-i]==1){
                    return true;
                }
            }
        }
        return false;
    }

    void placeQueen(){
        b[pos.r][pos.c]=1;
        placements.push_back(pos.r);
    }

    void backtrack(){
        pos.c--;
        b[placements[pos.c]][pos.c]=0;
        pos.r = placements[pos.c] +1;
        placements.pop_back();
        if(pos.r==size) backtrack();
    }

    bool canBacktrack(){
        if(pos.c==1 && placements[0]==size-1) return false;
        else return true;
    }

    void nextsol(){
        while(pos.c!=size){ //while the board is not filled
            if(pos.r==size && canBacktrack()){
                backtrack();
            } else if(pos.r==size && !canBacktrack()){
                break;
            }else if(!hasQueens()){
                placeQueen();
                pos.r=0;
                pos.c++;
            } else {
                pos.r++;
            }
        }
    }

    void print(){
        for(int i=0; i<size; i++){
            for(int j=0; j<size; j++){
                cout << b[i][j];
            }
            cout<<endl;
        }
        cout<<endl;
    }

};


int main(){

    Board board(11);
    board.print();
    while(true){
        board.nextsol();
        if(!board.canBacktrack()) break;
        cout << ++board.count << endl;
        board.backtrack();
    }
}
tinket 回答:n皇后问题程序仅适用于n <= 10,即使它应适用于所有n

您的代码段对我而言。通过valgrind运行它表明此行中的读取无效:

if(b[pos.r][pos.c-i]==1){

在功能hasQueens()中。实际上,在某些情况下pos.c-i变为负数:每当pos.c小于size时。

,

代码的组织混乱,我建议清楚地写出您的边界,而不是依赖于为col == 1和r == size停止(如果访问不正确,则可能导致段错误)。另外,NQueen问题有一个很好的递归解决方案,我建议也对此进行研究。

我能够对您的程序进行一些更改,并获得了11 x 11的预期答案,但是我认为代码中还有更多错误。问题出在backtrack()和placeQueen()函数上,pos.c递减而不检查它是否大于0,因此它可能变为负值并在访问时崩溃。最重要的是,您不需要在放置向量上执行push_back / pop_back,因为您知道您只能在每一列上放置一个皇后,因此它实际上应该是固定大小的。放置皇后时,可以放置[c] = r。希望这可以帮助。

本文链接:https://www.f2er.com/3162778.html

大家都在问