HZOJ#236. 递归实现组合型枚举

题目描述

​ 从 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等。在实际使用时,你可能需要添加这些检查以防止错误输入。

猜你喜欢

转载自blog.csdn.net/dsafefvf/article/details/132673329