时间限制:3000 ms  |  内存限制:65535 KB


难度:3


 

描述 找出从自然数1、2、... 、n(0<n<10)中任取r(0<r<=n)个数的所有组合。

 

输入 输入n、r。 输出 按特定顺序输出所有组合。

特定顺序:每一个组合中的值从大到小排列,组合之间按逆字典序排列。 样例输入

5 3

样例输出

543
542
541
532
531
521
432
431
421
321


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
using namespace std;
int n, r;
set <int> myset; //存放组合数
int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

void dfs(int i, int sum, int len){ //i:当前数字, sum: 当前组合数,len: 当前组合数的位数
if(len > r || i < 1)
return ;
if(len == r){
if(myset.count(sum) == 0){
myset.insert(sum);
}
return ;
}
dfs(i - 1, sum * 10 + a[i - 1], len + 1);
dfs(i - 1, sum, len);
}

int main(){

while(cin >> n >> r){
for(int i = n; i >= 1; i--){ //又高位枚举
dfs(i, i, 1);
}
set<int>::iterator it;
for(it = --myset.end(); it != myset.begin(); --it) //set已经自动由小到大排序,所以逆序输出
cout << *it << endl; //end()为最后一位的下一位,另外begin()为读出就跳出
cout << *it << endl; //输出最后一个
myset.clear(); //清空
}

return 0;
}