18712 递归实现组合

题目:
找出从自然数1、2、……、m中任取k个数的所有组合,组合中字典序大的先输出。
例如m=5,k=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

输入格式
两个整数m和k,(1<=k<=m<=10)

输出格式
按字典序输出所有组合

思路:
因为递归方法有很多人给出的原因这里就不再给出了
这里讲讲循环的方法
主要就是每次输出后最后一位数字都要加1
如果最后一位数为最大值的时候就让前面的那一位数+1
最后一位数变成前面那一位数再+1
前面的数以此类推也是这样
看是不是该位数的最大值
是就让前面一位数加1,并且该位数变成前面一位数再加1
知道第一个数字为最大值即可

AC代码

#include <iostream>

using namespace std;
int n,k;
int a[1000];
int b[1000];
int main()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++)a[i]=i;//初始化
    int j=0;
    for(int i=k;i>=1;i--){//记录每个位数的最大值
        b[i]=n-j;
        j++;
    }
    while(1){
            int i;
    int ok=1;
       if(a[1]>b[1])break;//如果第一个数超过最大值的时候就退出循环
    for(i=1;i<=k;i++){//输出
        cout<<a[i]<<' ';
        if(a[i]==b[i]&&i!=1&&ok){//如果目前的数正好是最大值的时候就把前面那一位数+1,自己变成前面那一位数再加1
            a[i-1]++;
            a[i]=a[i-1]+1;
            ok=0;
        }
        if(!ok&&a[i]==b[i]){//因为一次输出只能加一次1,如果前面加过一次1了之后是最大值就不用再加1了,直接变成前一位数+1就好
            a[i]=a[i-1]+1;
        }
    }
    if(ok)a[i-1]++;//如果整个循环没有最大值出现的情况就最后一个数+1
    cout<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值