N 皇后问题-回溯法

N 皇后问题:在 N × N  的棋盘上放置彼此不受攻击的 N 个皇后,任意两个皇后不同行、不同列、不同斜线。

思路

1. 因为皇后不能同行,所以,在每一行放置一个皇后就行

2. 当在一行放置皇后的时候:

     1) 顺序检查这一行每一个位置是否和上面所有的皇后,只要有一个同列或者在斜线上就不能放置;若找到一个满足的,放置在这个位置,开始下一行的皇后放置。

     2) 当此行所有位置都不满足时,回溯到上一行,让上一个行的皇后继续选择下一个合适的位置。

如此,直到所有行上都放上满足条件的皇后,即为一个解。

过程如下图所示:

《N 皇后问题-回溯法》

C++ 代码

#include <iostream>
#include <cmath>
#include <cstdlib>

using namespace std;

class Queen {
private:
    int n;
    int* x;
    int sum;
public:
    Queen(int n) {
        this->n = n;
        sum = 0;
        x = new int[n+1];
        for(int i=0; i <= n; i++)
            x[i]=0;
    }

    int getSum() {
        return sum;
    }

    void Backtrack(int t) {
        if (t > n) {
            for(int i=1; i <= n; i++) {
                for(int j=1; j <= n; j++)
                    if(j == x[i])
                        cout << "Q" << " ";
                    else
                        cout << "#" << " ";
                cout << endl;
            }
            cout << endl;
            sum++;
        } else
            for (int i=1; i <= n; i++) {
                x[t] = i;
                //cout << "i:" << i << " " << "x[t]:" << x[t] << " " << "t:" << t << endl;
                if(constraint(t))
                    Backtrack(t+1);
            }
    }

    bool constraint(int k) {// 约束条件
        for (int i=1; i < k; i++)
            if((abs(k-i)==abs(x[i]-x[k]))||(x[i]==x[k]))
                return false;
        return true;
    }

    ~Queen() {
        delete[] x;
    }
};

int main() {
    cout << "           ------N皇后问题------" << endl;
    cout << "之回溯法求解\n" << endl;
    cout << "请输入皇后的个数:";
    int n;
    cin >> n;
    Queen queen(n);
    cout << "\n" << n << "皇后问题的解为:" << endl;
    queen.Backtrack(1);
    cout << "\n总共有" << queen.getSum() << "个解" << endl;
    system("PAUSE");
    return 0;
}

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