描述
找出从自然数1、2、… 、n (0 < n < 10)中任取r ( 0 < r <= n )个数的所有组合。
输入
输入n、r。
输出
按特定顺序输出所有组合。
特定顺序:每一个组合中的值从大到小排列,组合之间按逆字典序排列。
样例输入
5 3
样例输出
543
542
541
532
531
521
432
431
421
321
题目有两种方式
1.next_permutation 全排列函数
2.dfs 递归
递归的做法
#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
int v[10],a[10];
int n,r;
int sign[10];
void dfs(int num)
{
int i;
if (num>r) //当个数达到r 输出 return
{
for (i=1; i<=r; i++)
{
cout<<a[i];
}
cout<<endl;
return;
}
for (i=1; i<=n; i++)
{
if (sign[i]==0&&(a[num-1]>v[i]||num==1)) //当没有被访问过, 且 他的前一位要大于当前位或者没有前一位
{
sign[i] = 1;
a[num] = v[i];
//cout<<a[num]<<endl;
dfs(num+1); //对一下进行判断
sign[i]=0;
}
}
}
int main()
{
cin>>n>>r;
int count1=1;
for (int i=n; i>0; i--)
{
v[count1] = i;
count1++;
}
dfs(1);
return 0;
}
全排列函数
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
int m;
bool ok (string s1) //判断是否满足每一位前面都大于后面的情况
{
char f;
f = s1[0];
int i;
for (i=1;i<m;i++)
{
if (f<s1[i])
return false;
f = s1[i];
}
return true;
}
int main()
{
int n;
cin>>n>>m;
string a,b;
int i;
for (i=n;i>0;i--)
a += i+'0';
b= "";
while (prev_permutation(a.begin(), a.end())) //全排列
{
if (ok(a)&&b!=a.substr(0,m))
{
b = a.substr(0,m);
cout<<b<<endl;
}
}
return 0;
}