题目描述
从 1−n 这 n 个整数中随机选取 m个,每种方案里的数从小到大排列,按字典序输出所有可能的选择方案。
输入
输入两个整数 n,m。(1≤m≤n≤10)
输出
每行一组方案,每组方案中两个数之间用空格分隔。
注意每行最后一个数后没有空格。
样例输入
3 2
样例输出
1 2
1 3
2 3
样例输入2
5 3
样例输出2
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <stack>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>
using namespace std;// 定义一个长度为10的数组arr,用于存储数据
int arr[10]; // 定义一个函数print_one_result,用于打印数组arr的一种特定排列结果
void print_one_result(int n) { // 循环打印数组arr的前n个元素,每个元素之间用空格隔开 for (int i = 0; i < n; i++) { if (i) cout << " "; // 如果不是第一个元素,打印一个空格 cout << arr[i]; // 打印当前元素 } cout << endl; // 换行,打印下一个结果时从新的一行开始 return ; // 函数结束,返回
} // 定义一个函数f,用于递归生成所有可能的数组排列
void f(int i, int j, int n, int m) { // 如果已经使用了m个不同的元素,打印当前排列结果并结束递归 if (i == m) { print_one_result(m); return ; } // 对于每个可能的元素k(从j开始到n),赋值给当前位置的元素,并递归调用f生成下一个位置的排列 for (int k = j; k <= n && m - i - 1 <= n - k; k++) { arr[i] = k; // 将k赋值给当前位置的元素 f(i + 1, k + 1, n, m); // 递归调用f生成下一个位置的排列,j加1是因为当前位置已经使用了k,下一个位置的元素只能在k+1之后 } return ; // 函数结束,返回
} // 主函数,程序从这里开始执行
int main() { // 从用户输入中读取n和m的值 int n, m; cin >> n >> m; // 调用函数f开始生成排列结果 f(0, 1, n, m); return 0; // 主函数结束,返回0表示程序正常结束
}
这段代码是一个C++程序,它的目的是生成所有可能的数组排列,使得数组的前m个元素都是不同的,且每个元素都在1到n的范围内。
具体来说,程序首先从用户输入n和m的值。然后,它调用函数f,该函数递归地生成所有可能的排列。
在函数f中,它首先检查是否已经到达了数组的末尾(即已经使用了m个不同的元素)。如果是,那么它就打印出当前的数组排列,然后返回。
否则,它将遍历数组中下一个元素的潜在值。对于每个可能的值k(从j开始,直到n),它将k赋值给当前位置的元素,并递归地调用函数f,将下一个位置、k+1作为新的j,n作为新的m。
在主函数main中,它从用户输入n和m的值,并调用函数f开始生成排列。
需要注意的是,这个程序没有对输入进行有效性检查,例如确保m小于等于n等。在实际使用时,你可能需要添加这些检查以防止错误输入。