5973 Problem B 【递归入门】组合的输出

389 篇文章 1 订阅
144 篇文章 2 订阅

问题 B: 【递归入门】组合的输出
时间限制: 1 Sec 内存限制: 128 MB
献花: 63 解决: 35
[献花][花圈][TK题库]
题目描述
排列与组合是常用的数学方法,其中组合就是从n个元素中抽出r个元素(不分顺序且r < = n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数。
现要求你不用递归的方法输出所有组合。
例如n = 5 ,r = 3 ,所有组合为:
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
输入
一行两个自然数n、r ( 1 < n < 21,1 < = r < = n )。
输出
所有的组合,每一个组合占一行且其中的元素按由小到大的顺序排列,所有的组合也按字典顺序。
提示

一.递归方式:

#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <set>

using namespace std;
int Max, Array[25] = { 0 };
bool hashTable[25] = { 0 };

void Generate(int n,int nowk,int next)
{
    if (nowk > Max)
    {
        for (int i = 1; i <= Max; ++i)
        {
            printf("%d", Array[i]);
            if (i != Max)
                printf(" ");
        }
        printf("\n");
        return;
    }

    for (int i = next;i <= n; ++i)
    {
        if (hashTable[i] == false)
        {
            Array[nowk] = i;
            hashTable[i] = true;
            Generate(n, nowk + 1, i + 1);
            hashTable[i] = false;
        }
    }
}

int main()
{
#ifdef _DEBUG
    freopen("data.txt", "r+", stdin);
#endif // _DEBUG

    int n;

    while (cin >> n >> Max)
    {
        Generate(n, 1,1);
    }



    return 0;
}

二.非递归版

#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <set>

using namespace std;

void permutation(int n, int m)
{
    vector<int> combine;
    stack<int> buf;
    bool pop = false;
    int top;

    buf.push(1);
    combine.push_back(1);

    while (buf.size())
    {
        if (combine.size() == m)
        {
            for (int i = 0; i < m; ++i)
            {
                printf("%d", combine[i]);
                if (i != m - 1)
                    printf(" ");
            }
            printf("\n");
            pop = true;
        }

        top = buf.top() + 1;
        if (top == n + 1)
        {
            pop = true;
            buf.pop();
            combine.pop_back();
            continue;
        }

        if (pop)
        {
            buf.pop();
            combine.pop_back();
            pop = false;
        }

        if (top <= n)
        {
            buf.push(top);
            combine.push_back(top);
        }
    }

}

int main()
{
#ifdef _DEBUG
    freopen("data.txt", "r+", stdin);
#endif // _DEBUG

    int n, m, PS = 0;

    while (cin >> n >> m)
    {
        permutation(n, m);
    }



    return 0;
}
/**************************************************************
    Problem: 5973
    User: Sharwen
    Language: C++
    Result: 升仙
    Time:94 ms
    Memory:1720 kb
****************************************************************/
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值