n皇后问题(C++解决)

来源:互联网 发布:什么是攻守道 知乎 编辑:程序博客网 时间:2024/05/18 00:29

n皇后问题源于8皇后问题。八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。

使用一个数组记录每个皇后应该放置的列数,static int locate[20]

统计可以允许n个皇后排列的情况种数,static int sum

当当前层的皇后位置确定后,就递进一层,也是选取下一行作为放置位置的意思。在下一行的位置中找到可以放置皇后的位置。如果直到第n行都可以找到皇后放置的位置,则sum++。然后退回上一层继续寻找允许排列的方案。

确定当前位置是否可以放置皇后,用place(n)函数实现:

bool place(int m){
    for(int i = 1; i < m; i++){
        if((locate[i] == locate[m])||(abs(m - i) == abs(locate[m] - locate[i])))
            return false;
    }
    return true;
}

递进一层用Back(n)函数实现:

void Back(int m){
    if(m > n)sum++;
    else{
        for(int i = 1; i <= n; i++){
                locate[m] = i;
            if(place(m))
                Back(m + 1);
        }
    }
}


完整代码如下:

#include <iostream>#include <stdlib.h>using namespace std;static int n, sum = 0;static int locate[20];bool place(int m){    for(int i = 1; i < m; i++){        if((locate[i] == locate[m])||(abs(m - i) == abs(locate[m] - locate[i])))            return false;    }    return true;}void Back(int m){    if(m > n)sum++;    else{        for(int i = 1; i <= n; i++){                locate[m] = i;            if(place(m))                Back(m + 1);        }    }}int main(){    cout<<"输入你想要的n:"<<endl;    cin>>n;    Back(1);    cout<<n<<"皇后共有"<<sum<<"种解法"<<endl;    return 0;}

运行结果如下:


1 0