N皇后问题

八皇后问题是一个古老而著名的问题,它是回溯算法的典型例题。该问题是十九世纪德国著名数学家高斯于1850年提出的:在8行8列的国际象棋棋盘上摆放着 八个皇后。若两个皇后位于同一行、同一列或同一对角线上,则称为它们为互相攻击。
现在要求使这八个皇后不能相互攻击,即任意两个皇后都不能处于同一行、同一列或同一对角线上,问有多少种摆法。

解题思路

在递归方式中,pos[i]表示第i行的皇后摆在第pos[i]列上。也可以使用循环来模拟递归过程。

实现代码

打印所有摆放方式:

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

class Queens {
public:
    int nQueens(int n) {
        vector<int> pos(n, 0);
        int i = 0;
        fun(n, pos, i);
        return 0;
    }

    void fun(int n, vector<int>& pos, int i)
    {
        if (i == n)
        {
            return;
        }
        for (int k = 0; k < n; k++)
        {
            pos[i] = k;
            if (check(pos, i))
            {
                if (i == n - 1)
                {
                    show(pos);
                }
                else
                {
                    fun(n, pos, i + 1);
                }
            }
        }
    }

    bool check(vector<int> pos, int i)
    {
        for (int k = 0; k < i; k++)
        {
            if (pos[k] == pos[i] || abs(k - i) == abs(pos[k] - pos[i]))
            {
                return false;
            }
        }
        return true;
    }

    void show(vector<int> pos)
    {
        for (int i = 0; i < pos.size(); i++)
        {
            for (int j = 0; j < pos.size(); j++)
            {
                if (pos[i] == j)
                {
                    cout<<'+'<<" ";
                }
                else
                {
                    cout<<'0'<<" ";
                }
            }
            cout<<endl;
        }
        cout<<endl;
    }
};

int main()
{
    Queens q;
    q.nQueens(8);
}

打印摆放种类:

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

class Queens {
public:
    int nQueens(int n) {
        vector<int> pos(n, 0);
//        递归方式
//        int count = 0;
//        fun(n, pos, 0, count);
//        return count;

//        非递归方式
        return fun2(n, pos);
    }

    //非递归方式
    int fun2(int n, vector<int> pos)
    {
        int i = 0;
        pos[i] = -1;
        int count = 0;
        while (i >= 0)
        {
            pos[i]++;
            while (pos[i] < n && !check(pos, i))
            {
                pos[i]++;
            }
            if (pos[i] < n)
            {
                if (i == n - 1)
                {
                    count++;
                }
                else
                {
                    i++;
                    pos[i] = -1;
                }
            }
            else
            {
                i--;
            }
        }

        return count;
    }

    //递归方式
    void fun(int n, vector<int>& pos, int i, int& count)
    {
        if (i == n)
        {
            return;
        }
        for (int k = 0; k < n; k++)
        {
            pos[i] = k;
            if (check(pos, i))
            {
                if (i == n - 1)
                {
                    count++;
                }
                else
                {
                    fun(n, pos, i + 1, count);
                }
            }
        }
    }

    bool check(vector<int> pos, int i)
    {
        for (int k = 0; k < i; k++)
        {
            if (pos[k] == pos[i] || abs(k - i) == abs(pos[k] - pos[i]))
            {
                return false;
            }
        }
        return true;
    }
};

int main()
{
    Queens q;
    for (int i = 1; i <= 12; i++)
    cout<<q.nQueens(i)<<endl;
}
上一篇:社区不是请客吃饭:如何加入 OpenStack 基金会


下一篇:长期维护嵌入式Linux内核变得容易