彩票复式投注程序(组合数产生方法)

时间:2025-01-26 17:56:36

 

// : Defines the entry point for the console application.
//
/*****************************************************
1.此程序是为彩票双色球复式投注编写,其功能为根据用户选择的红区,蓝区数字组合产生投注号码,
产生的注数以用户选择的红区蓝区数字个数不同而改变。
2.此程序产生双色球复式号码默认是红球区复式投主,固定蓝球区选择的号码来参与投注来产生号码的,若
  有人要进行篮球复式投注,在输入号码产生投注时,只需在提示红区输入时输入蓝区数,蓝区提示时输入红区数即可。
3.此程序也可产生单式投注号码
4.此程序在数字组合上可以产生从m个数选取n个数的任意个组合(为任意正整数),但此程序是为彩票投注编写,且带有中奖
  查询功能,因此在中奖查询时默认了产生每注号码只有7个数,若有其他需求,可简单修改此程序代码即可实现需求。
5.此程序也可以用来产生其他彩票的复式投注,只要是一注号码为7个数的都可以,如36选7等,只要输入的蓝区号码个数为0即可。
  若要用程序
6.此程序只是偶简单的写来玩的,没有细致去分析处理各种异常,谁有兴趣的可再去仔细研究,也用来大家交流组合数产生的算法。
7.此程序在产生大的组合时,如从1000个数中18个数的组合,理论上产生是没有问题的,只要你的机器内存足够大
,因为本程序在产生组合数时采用的是递归的方法,多重嵌套是内存空间的耗费需要考虑。另外此程序中的输入输出都是屏幕,一个改进
之处是输入输出都指向文本,尤其是对产生大组合的输出时,采用输出到文本可以看到全部组合。

***************************************************************************************///
#include ""
#include ""
#include ""


#define  U32  unsigned long 
#define MaxRedAreaNumCount         33  //空区最大可选数字 个数
#define MaxBlueAreaNumCount        16 // 蓝区最大可选数字个数

#define  HaveBlue           1   //是否有蓝区,若要玩其他彩票组合,没蓝区数字的此宏为0 ,如36选7的彩票

U32  uaRedAreaNum[MaxRedAreaNumCount] = {0};
U32  uaBlueAreaNum[MaxBlueAreaNumCount] = {0};
U32  uaCombination[10000][7]={{ 0 }}; //存储每注号码,为后面中奖查询用,这里只定位为可以存储10000注号码的中奖查询
U32  CombinationCount = 1; // 记录产生的符合要求的组合个数

/*****************************************
功能:产生组合数
入参: uSrcNum  :备选数集合,产生的组合数就是从这个集合中选出的
       uTotal   :备选数集合中数的个数
    uSeletc  :要从备选数中选择几个数来组合
       uPreNum  :本轮组合前的前置数集合
       uPreNum  :本轮组合前的前置数集合中有几个数
      uBlueNum  :产生的号码中蓝区号码,若非双色球投注,此值赋为0
出参: 无
备注:本函数是采用递归的方法产生组合数,基本思想是:

         把从n个数中选m个数的组合,逐层分解成求从n-1个数中选m-1个数,采用递归方法实现,递归结束位置为从p个数中选1个数的组合 

        (p为1~n之间的正整数)。为在逐层分解到最后时,就把一组组合输出,在每层向下递归时,都把前一次的不参加下次递归的数进行

       保存并做为前置数向下传递,这样到最后从p选1的组合 输出时,就一次性把整个组合数全部产生输出了。

*****************************************/
void Combination(U32 *uSrcNum , U32 uTotal ,U32 uSeletc, U32 *uPreNum, U32 uPreNunCount,U32 uBlueNum )
{
    U32 i =0 , j= 0, k =0, m = 0;
    U32 Temp[MaxRedAreaNumCount] = {0};
   
 //记录前置数
    for(m = 0 ; m < uPreNunCount; m++ )
    {
       Temp[m] =  uPreNum[m]; 
    } 
   
    for(i = 0; i < uTotal ; i++)
    {
       if(uTotal-i > uSeletc && uSeletc -1 > 0)
       {
            uPreNunCount++; //
            Temp[m] = uSrcNum[i];//前置数又增加了一个,保存起来。
            Combination (&uSrcNum[i+1],uTotal - i-1, uSeletc -1, Temp,uPreNunCount,uBlueNum);  
       }
       else
       {
             if(0 == i)//走到这里一般已经是转换为n选1了
             {
                   for(j = i; j < uTotal ; j++)
                   {
                       printf("第 %d 注: ",CombinationCount++); 

        for(k = 0; k < uPreNunCount ; k++)
        {
                          printf("%d/t",uPreNum[k]); //先输出前置数
                          uaCombination[CombinationCount-1][k] = uPreNum[k];//保存产生的组合数成员
        }
                     
                       printf("%d/t",uSrcNum[j]);  //剩余的每个数和前置数组合形成一注号码
        uaCombination[CombinationCount-1][k] = uSrcNum[j];//保存产生的组合数成员
        //配合上篮区号码输出
        if(0 !=uBlueNum)
        {
           printf("%d/n",uBlueNum); 
        uaCombination[CombinationCount-1][k+1] = uBlueNum;//保存产生的组合数成员
        }

                   }
             }
             else //走到这里一般是输出最后一柱组合了
             {
                 printf("第 %d 注: ",CombinationCount++); 
     for(k = 0; k < uPreNunCount ; k++)//先输出前置数
     {
                      printf("%d/t",uPreNum[k]); 
       uaCombination[CombinationCount-1][k] = uPreNum[k];//保存产生的组合数成员
     }
                
                  for(j = i; j < uTotal ; j++) //这里不再是剩余的每一个数和前置数组合而是剩余的所有数和前置数组合生成一注号码
                  {
                      printf("%d/t",uSrcNum[j]);
       uaCombination[CombinationCount-1][k++] = uSrcNum[j];//保存产生的组合数成员
                  }
                 
       //配合上篮区号码输出
      if(0 !=uBlueNum)
       {
       printf("%d/n",uBlueNum); 
       uaCombination[CombinationCount-1][k] = uBlueNum;//保存产生的组合数成员
       }
                
             }
            
             break; 
       }
      
         uPreNunCount-- ;   
         
    } 
}

 

/*****************************************
功能:组合号码中奖查询
入参: uLotteryWinRed :红区中奖号码集合

          uLotteryWinBlue :蓝区中奖号码集合

 出参: 无
备注:*****************************************/

void LotteryWinSee(U32 *uLotteryWinRed ,U32 *uLotteryWinBlue )
{
 U32 WinInfo[6] = {0};
 U32 i = 0,j=0;
 U32 Rcount = 0;
 U32 Bcount = 0;
 U32 NoWIn = 0;

    for(j =0; j < CombinationCount-1; j++)
 {
            Rcount = 0;  
      Bcount = 0;
   for(i =0; i < 6; i++) //红区中奖查询
   {
    if(uLotteryWinRed[i] == uaCombination[j][i])
    {
                  Rcount++;
    }
   }

   if(uLotteryWinBlue[0] == uaCombination[j][i]) //蓝区中奖查询
   {
    Bcount++;
   }

   if( 7 == Rcount + Bcount )
   {
                WinInfo[0]++;
   }
   else if(6 == Rcount )
   {
                 WinInfo[1]++;
   }
   else if(6 == Rcount + Bcount  )
   {
                  WinInfo[2]++;
   }
   else if(5 == Rcount + Bcount || 5 == Rcount )
   {
                 WinInfo[3]++;
   }
   else if(4 == Rcount + Bcount || 4 == Rcount )
   {
                 WinInfo[4]++;
   }
   else if(3 == Rcount + Bcount || 1 == Bcount ||2 == Rcount + Bcount)
   {
                 WinInfo[5]++;
   }
   else
   {
                NoWIn++;
   }
 }
 
 if( CombinationCount-1== NoWIn)
 {
       printf(" 很遗憾, 你没有中奖/n");

 }
 else
 {
  printf("/n中奖统计:/n");

  for(i =0; i < 6; i++)
  {
   if( 0 != WinInfo[i])
   {
     printf(" %d等奖:%d 注/n", i,WinInfo[i]);
   }
  }
 }

 

}
int main(int argc, char* argv[])
{
    U32 i =  0, j = 0;
    U32 uRedCount =  0; //记录红区选择的数的个数
    U32 uSelectCount = 0; //记录从备选数中选几个数来组合
    U32 uBlueCount  = 1; //记录蓝区选择的数的个数
 U32 uLotteryWinRed[10]= {0}; //记录中奖号码
 U32 uLotteryWinBlue[10]= {0}; //记录中奖号码
 
   printf("              双色球复式投注:/n");
   printf("红区:/n");
   while(1)
   {
     printf("请输入在红区要选择的被组合的数字个数(1~%d个):",MaxRedAreaNumCount); 
        scanf("%d/0" ,&uRedCount);
    
     printf("请输入在红区要选择的被组合的数字(1~%d个),以enter结束每个数输入:/n",uRedCount);    
     for(i =0; i < uRedCount; i++)
        scanf("%d/0" ,&uaRedAreaNum[i]);
       
     printf("请输入在备选数中选几个数来组合(1~%d个):", uRedCount); 
        scanf("%d/0",&uSelectCount); 
       
     if(uRedCount >= uSelectCount )
     {
         break;
     }
     else
     {
         printf("输入的组合数目比备选数多,请重新选择输入/n");       
     }
   }
 
#if HaveBlue
  printf("/n蓝区:/n");

    printf("请输入在蓝区要选择的被组合的数字个数(1~%d个):",MaxBlueAreaNumCount); 
        scanf("%d/0" ,&uBlueCount);
    
     printf("请输入在蓝区要选择的被组合的数字(1~%d个),以enter结束每个数输入:/n ",uBlueCount);    
     for(i =0; i < uBlueCount; i++)
        scanf("%d/0" ,&uaBlueAreaNum[i]);
#endif

//开始产生组合
  printf("/n/n");
  do{
    Combination(uaRedAreaNum, uRedCount ,uSelectCount, uaRedAreaNum, 0,uaBlueAreaNum[uBlueCount-1]);
    uBlueCount--;
   }while(uBlueCount>0);
  

 printf("/n你输入的选择共有 %d 组合/n",CombinationCount-1); 

    printf("/n中奖查询:/n");

 printf("/n/n请输入红区中奖号码(6个数),以enter结束每个数输入:/n");

 for(i =0; i < 6; i++)
  scanf("%d/0" ,&uLotteryWinRed[i]);

    printf("/n/n请输入蓝区中奖号码,以enter结束输入:");
 scanf("%d/0 ",&uLotteryWinBlue[0]);

    LotteryWinSee(uLotteryWinRed,uLotteryWinBlue );

    printf("/n/n");
 system("pause");
 return 0;
}