算法题:体彩29选7彩票组合(组合/回溯)

本文介绍了如何使用递归算法生成29选7彩票的所有不同数字组合,通过主函数和combine函数的配合,实现了从给定的数字集合中选择指定数量数字的组合生成和输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

算法题:体彩29选7彩票组合(组合/回溯)

假设有一种29选7的彩票,每注由7个1~29的数字组成,且这7个数字不能相同,编写程序生成所有的号码组合。

代码如下:

#include <stdio.h>
#define MAXN 7 //设置每一注彩票的位数
#define NUM 29 //设置组成彩票的数字
int num[NUM];
int lottery[MAXN];
void combine(int n, int m)
{
     int i,j;
     for(i=n;i>=m;i--)
     {
          lottery[m-1]=num[i-1];  //保存一位数字
          if (m>1)
               combine(i-1,m-1);
          else //若m=1,输出一注号码
          {
               for(j=MAXN-1;j>=0;j--)
                    printf("%3d",lottery[j]);
               getchar();
               printf("\n");
          }
     }
}

int main()
{
    int i,j;
    for(i=0;i<NUM;i++) //设置彩票各位数字
         num[i]=i+1;
    for(i=0;i<MAXN;i++)
         lottery[i]=0;
    combine(NUM,MAXN); 
    getchar();
    return 0;
}
预处理和全局变量
cCopy#include <stdio.h>
#define MAXN 7 //设置每一注彩票的位数
#define NUM 29 //设置组成彩票的数字
int num[NUM]; // 存储从1到29的数字
int lottery[MAXN]; // 用于存放当前生成的彩票号码

在这里,#define指令定义了每注彩票的数字位数(MAXN为7位)和可用于组成彩票的数字范围(NUM为29),即从1到29选择7个数字。数组num用于存储这些数字,而lottery数组则用于存储当前被选出来的一组彩票号码。

组合函数 combine
cCopyvoid combine(int n, int m) {
    int i,j;
    for(i=n;i>=m;i--) {
        lottery[m-1]=num[i-1]; //保存一位数字
        if (m>1)
            combine(i-1,m-1);
        else { //若m=1,输出一注号码
            for(j=MAXN-1;j>=0;j--)
                printf("%3d",lottery[j]);
            getch();
            printf("\n");
        }
    }
}

这是一个递归函数,其目的是生成所有可能的组合。它接收两个参数:n代表还可以选择的数字数量,m代表还需要选择的数字数量。算法的核心是递归地减少问题规模,直到达到基本情况(即需要选择的数字数量为0,m==1)时输出一种组合。

  • lottery[m-1]=num[i-1]; 这行将当前选定的数字加入到结果数组lottery中。
  • m>1,则继续递归寻找剩余的数字组合;否则,打印当前找到的一组完整的组合。
  • 注意,由于combine函数是以相反顺序填充lottery数组的,因此在打印时也要反向遍历lottery数组,以保证数字以正确的顺序显示。
主函数 main
cCopyint main() {
    int i,j;
    for(i=0;i<NUM;i++) //设置彩票各位数字
        num[i]=i+1;
    for(i=0;i<MAXN;i++)
        lottery[i]=0;
    combine(NUM,MAXN);
    getch();
    return 0;
}

主函数中,首先初始化num数组为1到29的整数,然后将lottery数组清零。之后调用combine函数开始生成所有可能的组合。combine(NUM,MAXN);这一行开始执行组合操作,即从29个数字中选择7个数字的所有组合。

注意事项
  1. 在原代码中使用getch();函数用于暂停屏幕输出。然而,请注意,getch()是属于conio.h库的一个函数,在某些编译器/环境中可能不可用或不标准。如果你遇到问题,可以尝试注释掉这些行或者使用其他方式实现类似的功能。
  2. 输出格式控制printf("%3d",lottery[j]);意味着每个数字占据至少3个字符宽度,以美化输出格式。
算法演示过程

假设我们从5个数字(1到5)中选择3个数字的所有可能组合,即NUM = 5MAXN = 3来代替原始的29和7(为简单起见,这里不修改原代码,仅作为例子说明)。这样,我们需要找出所有可能的从数字集合{1, 2, 3, 4, 5}中选择3个数字的组合。

让我们逐步跟踪函数combine(5, 3)的执行过程:

  1. 初始调用为combine(5, 3),此时n=5m=3
    • 循环i从5开始递减至3:

      • i=5时,lottery[2] = num[4] = 5,接着调用combine(4, 2)

        • combine(4, 2)中,循环i从4开始递减至2:
          • i=4时,lottery[1] = num[3] = 4,接着调用combine(3, 1)

            • combine(3, 1)中,循环i从3开始递减至1:
              • i=3时,lottery[0] = num[2] = 3,没有更多递归调用,打印组合3 4 5,对应的是从小到大选择数字。
              • i=2时,lottery[0] = num[1] = 2,同样没有更多递归调用,打印组合2 4 5
              • i=1时,lottery[0] = num[0] = 1,打印组合1 4 5
          • i=3时,流程类似,最终会打印组合1 3 5, 2 3 5

          • i=2时,流程类似,最终会打印组合1 2 5

      • i=4i=3时,通过类似的递归调用,会顺序打印出剩余的组合。

通过上述示例,你可以看到combine函数如何递归地构建每种可能的组合并打印它们。注意,这只是一个简化示例。在实际代码(使用29个数字中选择7个)中,组合的数量会大得多,但基本的执行过程相同:递归地选择每个数字,直到构建出完整的组合,然后打印该组合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

5-StarrySky

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值