递归问题-全排列问题和八皇后问题

递归问题-全排列问题和八皇后问题

  1. 不使用库函数实现全排列

    #include <cstdio>
    using namespace std;
    
    const int maxn = 11;
    
    int n,p[maxn],hashTable[maxn] = {false};
    
    void generateP(int index){
        if(index == n+1){
            for(int i = 1 ; i <= n ; i++){
                printf("%d",p[i]);
            }
            printf("\n");
            return ;
        }
        for(int x = 1 ; x <= n ; x++){
            if(hashTable[x] == false){
                p[index] = x;
                hashTable[x] = true;
                generateP(index+1);
                hashTable[x] = false;
            }
        }
    }
    
    int main(){
        n = 3;
        generateP(1);
    
        return 0;
    }
    

    《递归问题-全排列问题和八皇后问题》

  2. 八皇后问题

    • 在全排列的代码基础上进行求解的暴力解法。(此时保证了每行,每列都不相同)
    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    const int maxn = 11;
    int n,cnt = 0,p[maxn],hashTable[maxn] = {false};
    void generateP(int index){
        if(index == n+1){
            bool flag = true;
            for(int i = 1 ; i <= n ; i++){
                for(int j = i+1 ; j <= n ; j++){
                    if(abs(i-j) == abs(p[i]-p[j])){	// 是否在同一条对角线上
                        flag = false;
                    }
                }
            }
            if(flag == true) cnt++;
            return;
        }
        for(int x = 1 ; x <= n ; x++){
            if(hashTable[x] == false){
                p[index] = x;
                hashTable[x] = true;
                generateP(index+1);
                hashTable[x] = false;
            }
        }
    }
    int main(){
        n = 8;
        generateP(1);
        printf("%d",cnt);
        return 0;
    }
    
    • 一般来说,如果在到达递归边界前的某层,由于一些事实导致已经不需要往任何一个子问题递归,就可以直接返回上一层。一般把这种做法称为回溯法
    void generateP(int index)
    {
        if (index == n + 1)
        {
            cnt++;
            return; // 能够到达这里一定是合法的
        }
        for (int x = 1; x <= n; x++)
        {
            if (hashTable[x] == false)
            {
                bool flag = true;
                for (int pre = 1; pre < index; pre++)
                {
                    // 第index列的皇后的行号为x,第pre列皇后的行号为P[pre]
                    if (abs(index - pre) == abs(x - p[pre]))
                    {
                        flag = false; // 与之前的皇后在一条对角线上
                        break;
                    }
                }
                if (flag)
                {
                    p[index] = x;
                    hashTable[x] = true;
                    generateP(index+1);
                    hashTable[x] = false;
                }
            }
        }
    }
    

    《递归问题-全排列问题和八皇后问题》

    原文作者:八皇后问题
    原文地址: https://blog.csdn.net/xr469786706/article/details/88723371
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞