1、题目描述
从1 ~n这n个整数中随机选出m个,输出所有可能的选择方案。
输入格式
两个整数 n,m,在同一行用空格隔开。
输出格式
按照从小到大的顺序输出所有方案,每行1个。首先,同一行内的数升序排列,相邻两个数用一个空格隔开。其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面(例如 1 3 5 7
排在 1 3 6 8
前面)。
数据范围
n > 0,
0m
n,
n + (n - m) 25
输入样例
4 2
输出样例
1 2 1 3 1 4 2 3 2 4 3 4
2、题目解析
该题和递归实现排列型枚举有点类似,只不过是从选取部分数据,稍微有点区别。都采用dfs深度递归搜索树。
代码如下:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
/**
* 方法采用
* 依次枚举每个位置放哪个数
*
*/
int n,m;
const int N = 25;
int datas[N] = {0}; // 数据状态数组,0表示还没有被选择,1表示被选择了
int loc[N] = {0}; // 位置状态数组,0表示还没有被安排,否则表示被安排了
void dfs(int k){ // k表示到第几个位置了
if(k > m){ // 到深度递归的底部了,输出来并且结束递归
for(int i = 1; i <= m;++i)
printf("%d ",loc[i]);
getchar();
printf("\n");
return;
}
/*****/
for(int i = 1; i<= n;++i){ // 依次枚举当前位置可以选择的数据,采用dfs深度递归
if(datas[i] == 0 && i > loc[k - 1]){ // 保证所选择的数所组成的序列为升序
loc[k] = i; // 当前位置安排当前未选择的最小的数
datas[i] = 1; // 当前被选中的数的状态变为1
dfs(k + 1); // 深度递归下一个位置
// 现场恢复
datas[i] = 0;
loc[k] = 0;
}
}
}
int main()
{
scanf("%d%d",&n,&m);
dfs(1);
return 0;
}