- 题目:从 1∼n 这 n 个整数中随机选出 m 个,输出所有可能的选择方案。
- 输入格式: 两个整数 n,m ,在同一行用空格隔开。
- 数据范围:n>0; m∈[0,n]; n+(n-m) <= 25;
- 输出格式:
- 按照从小到大的顺序输出所有方案,每行 1 个。
- 首先,同一行内的数升序排列,相邻两个数用一个空格隔开。
- 其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面(例如 1 3 5 7 排在 1 3 6 8 前面)。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
int m;
const int N = 30;
int arr[N];
bool used[N];
/*start表示数字循环的起始指针
比如输入5 3:
第一层循环从1到5(从左至右)
第二层中:
以1开始的支点的分支就从2开始到5
以2开始的分支点的分支就从3开始到5
以3开始的分支点的分支就从4开始到5
以4开始的分支的的分支就从5开始到5
*/
void dfs(int u,int start,int m){
if(u > m){
for(int i = 1;i <= m; i ++){
cout<<arr[i]<<" ";
}
cout<<endl;
return;
}
for(int i = start; i <= n; i++){
if(!used[i]){
arr[u] = i;
used[i] = true;
dfs(u + 1,i + 1,m);//移到下一个坑位 start也相对于上一个分支加1
arr[u] = 0;
used[i] = false;
}
}
}
int main(){
cin>>n>>m;
dfs(1,1,m);//从第一个坑位开始 start从1开始 选择m个坑位
return 0;
}
若是输出所有结果:非升序的情况:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
int m;
const int N = 30;
int arr[N];
bool used[N];
void dfs(int u,int m){
if(u > m){
for(int i = 1;i <= m; i ++){
cout<<arr[i]<<" ";
}
cout<<endl;
return;
}
for(int i = 1; i <= n; i++){
if(!used[i]){
arr[u] = i;
used[i] = true;
dfs(u + 1,m);
arr[u] = 0;
used[i] = false;
}
}
}
int main(){
cin>>n>>m;
dfs(1,m);
return 0;
}