【深度优先搜素(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("\n");
            }
            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("\n");
            }
            else{
                dfs(deep+1);
            }

        }

}

 

posted @ 2017-07-27 14:20  路人姜。  阅读(627)  评论(0编辑  收藏  举报