zoukankan      html  css  js  c++  java
  • 递归

    例题:

    n皇后问题

    Problem Description:
    在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
    你的任务是,对于给定的N,求出有多少种合法的放置方法。

    Input:
    共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。

    Output:
    共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。

     思路:

    在全排列上进行求解,由于当达到递归边界时表示生成了一个排列,所以需要在其内部判断是否为合法方案,即遍历每两个皇后,判断他们是否在同一条对角线上,如果不是则累计计数变量count。采用枚举法

    代码:

    int count=0;
    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){
                count++;
            }
            return ;
        }
        for(int x=1;x<=n;x++){
            if(hashTable[x]==false){
                P[index]=x;
                hashTable[x]=true;
                generateP(index+1);
                hashTable[x]=false; 
            }
        }
    }

    回溯法:

    一般来说,如果在到达递归边界前的某层,由于一些事实导致已经不需要往任何一个子问题递归,就可以返回上一层。

    void generateP(int index){
        if(index==n+1){//递归边界 
            count++;
            return; 
        }
        for(int x=1;x<=n;x++){//第x行 
            if(hashTable[x]==false){//第x行没有皇后 
                bool flag=true;//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){//如果可以把皇后放在第x行 
                    P[index]=x;//令第index列皇后的行号为x 
                    hashTable[x]==true;//第x行已被占用 
                    generateP(index+1);//递归处理第index+1行皇后 
                    hashTable[x]=false;//递归完毕,还原第x行为未占用 
                }
            }
        }
    }
  • 相关阅读:
    cf D. Vessels
    cf C. Hamburgers
    zoj 3758 Singles' Day
    zoj 3777 Problem Arrangement
    zoj 3778 Talented Chef
    hdu 5087 Revenge of LIS II
    zoj 3785 What day is that day?
    zoj 3787 Access System
    判断给定图是否存在合法拓扑排序
    树-堆结构练习——合并果子之哈夫曼树
  • 原文地址:https://www.cnblogs.com/ak918xp/p/13461977.html
Copyright © 2011-2022 走看看