Description
找出从自然数1、2、… 、n(0<n<10)中任取r(0<r<=n)个数的所有组合。
Input
输入n、r。
Output
按特定顺序输出所有组合。
特定顺序:每一个组合中的值从大到小排列,组合之间按逆字典序排列。
Sample Input
5 3
Sample Output
543
542
541
532
531
521
432
431
421
321
思路:对于每个数我们可以选也可以不选,就是深度搜索问题,从大到小遍历一次
#include<stdio.h>
int n,m;
int a[100];
void dfs(int n,int m)
{
for(int i=n;i>=1;i--){
a[m]=i;
if(m>1)dfs(i-1,m-1);
else {
for(int i=a[0];i>=1;i--)
printf("%d",a[i]);
printf("\n");
}
}
}
int main()
{
scanf("%d%d",&n,&m);
a[0]=m;
dfs(n,m);
return 0;
}
问题来了:如果从小到大排列该如何做呢?
同样的方法,从小到大依次遍历,深度搜索.
#include<stdio.h>
int n,m;
int arr[100];
int vis[100];
void dfs(int cur)
{
if(cur==m+1){
for(int i=1;i<=m;i++)printf("%d",arr[i]);
printf("\n");
return;
}
for(int i=1;i<=n;i++){
if(vis[i]||i<=arr[cur-1])continue; //剪枝
arr[cur]=i; //选第i个数
vis[i]=1; //记录这个数是否被选
dfs(cur+1);
vis[i]=0; //恢复现场
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
dfs(1);
}
return 0;
}