zoukankan      html  css  js  c++  java
  • (算法)N皇后问题

    题目:

    八皇后问题:在8 X 8的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后不得处于同一行,同一列或者同意对角线上,求出所有符合条件的摆法。

    思路:

    1、回溯法

    数据结构:

    由于8个皇后不能处在同一行,那么肯定每个皇后占据一行,这样可以定义一个数组A[8],数组中第i个数字,即A[i]表示位于第i行的皇后的列号。

    满足条件:任意两个皇后不同列,即A[i]!=A[j],任意两个皇后不在同一对角线上,即abs(i-j)!=abs(A[i]-A[j])。

    算法:

    回溯法,通过深度遍历的形式枚举数组A的所有排列组合,并通过剪枝的形式(判断是否满足上述的条件)来减少不必要的计算量,详见代码。

    2、全排列法

    思路与字符串排列一样http://www.cnblogs.com/AndyJee/p/4655485.html,只是还需要对每一种排列做判断。

    数据结构:

    8个皇后不能处在同一行,那么肯定每个皇后占据一行,这样可以定义一个数组A[8],数组中第i个数字,即A[i]表示位于第i行的皇后的列号,先把数组A[8]分别用0-7初始化。

    满足条件:由于我们用0-7这7个不同的数字初始化数组,因此任意两个皇后肯定也不同列,那么我们只需要判断每个排列对应的8个皇后中是否有任意两个在同一对角线上即可,即对于数组的两个下标i和j,如果i-j==A[i]-A[j]或i-j==A[j]-A[i],则认为有两个元素位于了同一个对角线上,则该排列不符合条件。

    思路:

    参考字符串排列:

    求整个字符串的排列,可以分成两步:首先求所有可能出现在第一个位置的字符,即把第一个字符和后面的所有字符交换;然后固定第一个字符,求后面所有字符的排序。此时仍把后面的字符看成两部分,第一个字符和后面的字符,然后重复上述步骤。(递归)

    然后判断每一种排列是否满足上述添加即可。

    代码:

    1、回溯法

    #include <iostream>
    #include <vector>
    #include <stdlib.h>
    
    using namespace std;
    int count=0;
    
    bool canPlace(int index,const vector<int> &result){
        for(int i=0;i<index;i++){
            if(result[index]==result[i] || abs(index-i)==abs(result[index]-result[i]))
                return false;
        }
        return true;
    }
    
    void queen(int index,vector<int> &result,int N){
        if(index==N){
            for(int i=0;i<N;i++)
                cout<<result[i]<<" ";
            cout<<endl;
            count++;
            return;
        }
        for(int i=0;i<N;i++){
            result[index]=i;
            if(canPlace(index,result))
                queen(index+1,result,N);
        }
    }
    
    
    int main()
    {
        int n=8;
        vector<int> result;
    
        for(int i=0;i<n;i++)
            result.push_back(i);
        queen(0,result,n);
        cout<<count<<endl;
        return 0;
    }

    2、全排列法

    #include <iostream>
    #include <vector>
    #include <stdlib.h>
    
    using namespace std;
    int count=0;
    
    void swap(int *a,int *b){
        int tmp=*a;
        *a=*b;
        *b=tmp;
    }
    
    void queen_permutation(vector<int> &result,int index,int len){
        bool can=true;
        if(index==len-1){
            for(int i=0;i<len;i++){
                for(int j=i+1;j<len;j++){
                    if(i-j==result[i]-result[j] || i-j==result[j]-result[i]){
                        can=false;
                        break;
                    }
                }
                if(can==false)
                    break;
            }
            if(can){
                for(int i=0;i<len;i++)
                    cout<<result[i];
                cout<<endl;
                count++;
            }
        }
        else{
            for(int i=index;i<len;i++){
                swap(result[index],result[i]);
                queen_permutation(result,index+1,len);
                swap(result[index],result[i]);
            }
        }
    }
    
    
    int main()
    {
        int n=8;
        vector<int> result;
    
        for(int i=0;i<n;i++)
            result.push_back(i);
        queen_permutation(result,0,n);
        cout<<count<<endl;
        return 0;
    }
  • 相关阅读:
    muduo源代码分析--Reactor在模型muduo使用(两)
    uinty3d导入错误问题解决
    道量化交易程序猿(25)--Cointrader之MarketData市场数据实体(12)
    CSS cursor 属性
    手动挖第一桶金,10日赚3十万元
    JavaScript取出字符串和尾随空格
    编程的子阵列和最大和膨胀的美(可连接的端到端)
    OpenCV图像的基础叠加
    [SCSS] Organize SCSS into Multiple Files with Partials
    [CSS Flex] Justify-content
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4673893.html
Copyright © 2011-2022 走看看