• 【深度优先搜素(DFS)】桐桐的组合(UPCOJ3597)


    3597: 【搜索】桐桐的组合

    时间限制: 1 Sec  内存限制: 64 MB

    题目描述

    排列与组合是常用的数学方法,桐桐刚刚学会了全排列,就想试试组合,组合就是从n个元素中抽出r个元素(不分顺序且r≤n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数。

    输入

    两个整数n和r(1≤r≤n≤20)。

    输出

    输出所有的组合,每一个组合占一行且其中的元素按由小到大的顺序排列,每个元素占三个字符的位置,所有的组合也按字典顺序。

    样例输入

    5 3
    

    样例输出

      1  2  3
      1  2  4
      1  2  5
      1  3  4
      1  3  5
      1  4  5
      2  3  4
      2  3  5
      2  4  5
      3  4  5

    分析

    考察深度搜索,搜索+回溯。

    参考代码

     这个代码的b数组没有用,修改见下一个代码。

    /**
    n=4,r=3
    
    dfs(1)
    deep=1,
    i=1//前一个选定的数加1开始循环,前第一次选定的数是0
    ans[1]=1,
    b[21]={0,1,0,0,0,……},
    
    dfs(2)
    deep=2,
    i=2//前一个选定的数加1开始循环,前一个选定的数是1
    ans[2]=2,
    b[21]={0,1,1,0,0,……},
    
    dfs(3)
    deep=3
    i=3,
    ans[3]=3,
    b[21]={0,1,1,1,0……},
    deep=r=3
    printf,1,2,3
    b[21]={0,1,1,0,0,……},//回溯,因为1,2{3,4}循环完,后面还得循环1,3,{4}
    i=4//继续for循环
    ans[3]=4
    b[21]={0,1,1,0,1,……}
    deep=r=3
    printf,1,2,4
    b[21]={0,1,1,0,0,……}//回溯
    i=5>n
    
    dfs(2)//第三个数循环完了,返回到第二个数
    b[21]={0,1,0,0,0,……}//回溯
    i=3,
    ans[2]=3,
    b[21]={0,1,0,1,0,……}
    
    dfs(3)
    
    ……  ……
    
    */
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    using namespace std;
    int n,r;
    int ans[21];
    int b[21];//全局变量自动初始化为0
    void dfs(int deep);
    int main()
    {
        scanf("%d%d",&n,&r);
        dfs(1);
        return 0;
    
    }
    void dfs(int deep){
        int i;
        /**
        从上一个选定数加1开始循环,比如,
        1,2,3;1,2,4;1,2,5;是从2加1开始循环的
        */
            for(i=ans[deep-1]+1;i<=n;i++){
                if(!b[i]){
                    ans[deep]=i;
                b[i]=1;
                if(deep==r){
                    for(int j=1;j<=r;j++){
                        printf("%3d",ans[j]);
                    }
                    printf("
    ");
                }
                else{
                    dfs(deep+1);
                }
                b[i]=0;
                }
    
            }
    
    }

     删掉b数组,09.14

    /**
    上面的代码只是标记b的元素然而并没有用到标记数组所以删了也能AC
    n=4,r=3
    
    dfs(1)
    deep=1,
    i=1//前一个选定的数加1开始循环,前第一次选定的数是0
    ans[1]=1,
    
    dfs(2)
    deep=2,
    i=2//前一个选定的数加1开始循环,前一个选定的数是1
    ans[2]=2,
    
    dfs(3)
    deep=3
    i=3,
    ans[3]=3,
    deep=r=3
    printf,1,2,3
    i=4//继续for循环
    ans[3]=4
    deep=r=3
    printf,1,2,4
    i=5>n
    
    dfs(2)//第三个数循环完了,返回到第二个数
    i=3,
    ans[2]=3,
    
    dfs(3)
    
    ……  ……
    
    */
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    using namespace std;
    int n,r;
    int ans[21];
    void dfs(int deep);
    int main()
    {
        scanf("%d%d",&n,&r);
        dfs(1);
        return 0;
    
    }
    void dfs(int deep){
        int i;
        /**
        从上一个选定数加1开始循环,比如,
        1,2,3;1,2,4;1,2,5;是从2加1开始循环的
        */
            for(i=ans[deep-1]+1;i<=n;i++){
                    ans[deep]=i;
                if(deep==r){
                    for(int j=1;j<=r;j++){
                        printf("%3d",ans[j]);
                    }
                    printf("
    ");
                }
                else{
                    dfs(deep+1);
                }
    
            }
    
    }
    祝你早日攒够失望,然后开始新的生活。
  • 相关阅读:
    外卖 CPS
    拼多多虚拟产品搬砖玩法
    搞笑表情包
    读书
    抖音跑步赚钱
    bootstrapTable固定表头,表头错位问题
    关闭离开页面浏览器提示"确实要离开吗"
    子页面如何调用/关闭父页面layer
    BootstrapValidator 解决多属性被同时校验问题
    使用备份文件新建数据库Web框架
  • 原文地址:https://www.cnblogs.com/LuRenJiang/p/7244295.html
Copyright © 2020-2023  润新知