题目32:组合数

题目链接:

http://acm.nyist.net/JudgeOnline/problem.php?pid=32

描述

找出从自然数1、2、… 、n(0 < n < 10)中任取r(0<r≤n)个数的所有组合。

输入

输入n、r。

输出

按特定顺序输出所有组合。
特定顺序:每一个组合中的值从大到小排列,组合之间按逆字典序排列。

样例输入

5 3

样例输出

543
542
541
532
531
521
432
431
421
321

算法思想:

这个题目经典组合生成算法,经典组合生成算法如下图所示:
这里写图片描述
这道题所要求的是对输出进行简单的修改,将从小到大输出改为从大到小输出。所以,算法也需要做相应的修改。
首先,a[0…r]赋初值(最大值),并输出;
然后从右往左扫描a[0…r],查找第一个大于r - i的数,如果存在这样的数a[k],则将a[k]- -,并更新a[k]右边的数,a[j] = a[j - 1] + 1,j = k + 1,k + 2,…r。输出组合。
如果不存在,则说明组合已经完全生成,达到了最小值。

源代码

#include <iostream>
using namespace std;
void assemble(int n, int r)
{
    int *a = new int[r];
    for (int i = 0; i < r; i++)
    {
        //赋值最大值,即初值
        a[i] = n - i;
        cout << a[i];
    }
    cout << endl;
    for (int i = r - 1; i >= 0; i--)
    {
        //cout << "i = " << i << "," << "a[i] = " << a[i] << "," << "r = " << r << endl;
        //从右往左扫描查找大于r - i的数,如果存在,则将其a[i]--,并更新a[i]后的数
        if (a[i] > r - i)
        {
            a[i]--;
            for (int j = i + 1; j < r; j++)
            {
                a[j] = a[i] - j + i;
            }
            for (int i = 0; i < r; i++)
            {
                cout << a[i];
            }
            cout << endl;
            //回溯
            i = r;
        }
    }
}
int main()
{
    int n, r;
    cin >> n >> r;
    assemble(n,r);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值