题目:
找出从自然数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;
}