• 八皇后问题N种解法


        主要包括全排列和回溯两类,其中全排列可以递归与非递归,回溯也可以递归与非递归。于是加一起有4种解法。

    #include <iostream>
    #include <algorithm>
     
    using namespace std;
     
    template <size_t N> struct ArraySizeHelper {char _[N];};
    template <typename T, size_t N> ArraySizeHelper<N> makeArraySizeHelper(T(&)[N]);
    #define ARRAY_SIZE(a) sizeof(makeArraySizeHelper(a))
     
    bool valid_permutation(const int *queen, int len)
    {
        bool valid = true;
     
        for (int i = 0; i < len; ++i)
        {
            for (int j = i + 1; j < len; ++j)
            {
                if (queen[j] - queen[i] == j - i || queen[j] - queen[i] == i - j)
                {
                    valid = false;
                }
            }
        }
     
        return valid;
    }
     
    // Solved by permutation non recursion.
    int eightqueen_permutation_non_recur()
    {
        int queen[] = {0, 1, 2, 3, 4, 5, 6, 7};
        int count = 0;
     
        do
        {
            if (valid_permutation(queen, (int)ARRAY_SIZE(queen))) ++count;
        }
        while(next_permutation(queen, queen + ARRAY_SIZE(queen)));
     
        return count;
    }
     
    void permutation(int *queen, int len, int idx, int &count)
    {
        if (idx == len)
        {
            if (valid_permutation(queen, len)) ++count;
        }
        else
        {
            for (int i = idx; i < len; ++i)
            {
                swap(queen[i], queen[idx]);
                permutation(queen, len, idx + 1, count);
                swap(queen[i], queen[idx]);
            }
        }
    }
     
    // Solved by permutation recursion.
    int eightqueen_permutation_recur()
    {
        int queen[] = {0, 1, 2, 3, 4, 5, 6, 7};
        int count = 0;
     
        permutation(queen, (int)ARRAY_SIZE(queen), 0, count);
     
        return count;
    }
     
    bool valid_backtracking(const int *queen, int len)
    {
        for (int i = 0; i < len; ++i)
        {
            const int diff = abs(queen[i] - queen[len]);
            if (diff == 0 || diff == len - i) return false;
        }
     
        return true;
    }
     
    void placequeen(int *queen, int len, int idx, int &count)
    {
        if (idx == len)
        {
            ++count;
        }
        else
        {
            for (int i = 0; i < len; ++i)
            {
                queen[idx] = i;
     
                if (valid_backtracking(queen, idx))
                {
                    placequeen(queen, len, idx + 1, count);
                }
            }
        }
    }
     
    // Solved by backtracking(DFS) recursion.
    int eightqueen_backtracking_recur()
    {
        int queen[8];
        int count = 0;
     
        placequeen(queen, (int)ARRAY_SIZE(queen), 0, count);
     
        return count;
    }
     
    // Solved by backtracking(DFS) non recursion.
    int eightqueen_backtracking_non_recur()
    {
        int queen[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
        int count = 0;
        int step = 0;
     
        while(step >= 0)
        {
            bool valid = false;
     
            for (int i = queen[step] + 1; i < (int)ARRAY_SIZE(queen); ++i)
            {
                queen[step] = i;
     
                if (valid_backtracking(queen, step))
                {
                    step += 1;
                    valid = true;
                    break;
                }
            }
     
            if (!valid)
            {
                queen[step] = -1;
                step -= 1;
            }
            else if (step >= 8)
            {
                ++count;
                step -= 1;
            }
        }
     
        return count;
    }
     
    int main()
    {
        cout << eightqueen_permutation_recur() << endl;
        cout << eightqueen_permutation_non_recur() << endl;
        cout << eightqueen_backtracking_recur() << endl;
        cout << eightqueen_backtracking_non_recur() << endl;
     
        return 0;
    }
  • 相关阅读:
    【贪心 堆】luoguP2672 推销员
    【贪心 思维题】[USACO13MAR]扑克牌型Poker Hands
    「整理」[图论]最短路系列
    收集到的小玩意儿
    初遇构造函数
    在2440开发板液晶上显示两行字
    error: converting to execution character set: Invalid or incomplete multibyte or wide character
    宽字节
    宽字符wchar_t和窄字符char区别和相互转换
    linux获取文件大小的函数
  • 原文地址:https://www.cnblogs.com/codingmylife/p/2711839.html
Copyright © 2020-2023  润新知