• 1.25回溯 n皇后问题,素数环,困难的串


    回溯:当把问题分成若干个步骤时,如果当前部骤没有合法选择,则函数将返回上一级递归调用,这种现象称为回溯,因此,递归枚举算法有常被称为回溯法;

    n皇后问题: 思考:1。从64个格子选出一个子集使得任意一个格子不在同一行同一列同一对角线上,即子集枚举问题,64个格子的子集有2^64个,太大不够好

    2。从64个格子里选出8个格子,即组合生成问题,有C8 64 =4*10^9 种方案,仍不够好

    继而发现:恰每行每列格放置一个皇后,如果用c[x]表示第x行皇后的列,则只有8!=40320种排列

    实现: 数组坐标化 同一列 x1=x2 同一主对角线 y1-x1=y2-x2 同一副对角线 y1+x1=y2+x2

    用数组 储存各皇后 的 这三项参数值

    ~如果有多组数据,先预处理打表,防止重复计算超时

    #include<cstdio>
    #include<cstring>
    using namespace std;
    int c[15],n,ans[15],k=0;
    int idx[5][40];
    
    void dfs(int cur){
        if(cur>=n){k++; return;}
        for(int i=0;i<n;i++){
            if(!idx[0][i]&&!idx[1][cur+i]&&!idx[2][n+cur-i])
            {idx[0][i]=idx[1][cur+i]=idx[2][n+cur-i]=1;
            dfs(cur+1);
            idx[0][i]=idx[1][cur+i]=idx[2][n+cur-i]=0;
            }
        }
    }
    int main(){
        for(int i=1;i<11;i++){
            n=i; k=0;
            dfs(0);
            ans[i]=k;
        }
    //freopen("ans.txt","w",stdout);
        while(scanf("%d",&n)!=EOF&&n){
    
          printf("%d
    ",ans[n]);
        }
    }

    素数环 uva 524

    ~事先素数打表

    ~奇偶剪枝

    #include<cstdio>
    using namespace std;
    int a[20]={0},b[20],c[40]={0},n,ks=0;;
    void dfs(int cur){
        if(cur>n&&c[b[n]+1]){ 
           for(int i=1;i<=n;i++)
           if(i!=1)printf(" %d",b[i]);
           else printf("%d",b[i]);
            printf("
    ");
            return ;
        }
    //奇偶剪枝  
        if(cur%2==1){                  
            for(int i=3;i<=n;i+=2){
                if(c[i+b[cur-1]]&&!a[i]){
                    a[i]=1; b[cur]=i;
                    dfs(cur+1);
                    a[i]=0;
                }
                
            }
        }
        else  for(int i=2;i<=n;i+=2){
                if(c[i+b[cur-1]]&&!a[i]){
                    a[i]=1; b[cur]=i;
                    dfs(cur+1);
                    a[i]=0;
                }
                
            }
        
    }
    
    int main(){
        b[1]=1;
        c[2]=c[3]=c[5]=c[7]=c[11]=c[13]=c[17]=c[19]=c[23]=c[29]=c[31]=1;//素数打表 
        while(scanf("%d",&n)!=EOF){
                    if(ks)printf("
    ");
            printf("Case %d:
    ",++ks);
            dfs(2);
    
        }
        
        
        return 0;
    }
  • 相关阅读:
    变Win 2003为工作站
    搞笑短信
    ECC加密算法入门介绍
    搞笑短信
    万能Ghost系统制作教程
    “注册编辑已被管理员停用”之解决办法
    让Win7任务栏的“库”显示“我的电脑”
    全景拼图利器PTGui Pro 9.1.6 Retail汉化版
    Win7远程桌面不能连接的解决方案
    到底谁霸占了A类的IP地址
  • 原文地址:https://www.cnblogs.com/-ifrush/p/10319977.html
Copyright © 2020-2023  润新知