组合数问题

组合数问题:

描述:

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

示例:

输入n、r。

输出

按特定顺序输出所有组合。

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

算法分析:

该问题可以从具体的某个数据开始,例先尝试编写n=5r=3时列出所有组合数

从中发现规律,再而进行求解。

我们先从n=5 r=4的问题入手。我们手动按字典序列书写所有组合情况:

1234

1235

1245

1345

2345

观察发现,第一个位置元素有两种情况,即以1开头,以2开头,这是必想到要进行一个循环;再观察第二个位置元素,也是分几种情况,此时又要进行循环,并且是在上一个循环内部进行,同理第三个也是,第四个也是,但此时要输出这四个数字。

代码实现:

#include<stdio.h>

int main()

{

         inta[5]={1,2,3,4,5};

         inti,j,k,n,h,m; 

         i=-1;

         while(1){//第一个位置下标

                   i++;

                   j=i;

                   while(1){//第二个位置下标

                            j++;

                            h=j;

                            while(1){  //第三个位置下标

                                     h++;

                                     m=h;

                                     while(1){//第四个位置下标

                                               m++;                                             

                                               printf("%d%d %d %d\n",a[i],a[j],a[h],a[m]);

                                               if(m>=4)//循环结束条件,m的值只取3 4

                                                        break;

                                     }if(h>=3)   //循环结束条件 h的值可取2 3           

                                               break;

                            }

                            if(j>=2)

                                     break;

                   }if(i>=1)

                            break;

         }

         return0;

}

由此代码观察发现,若r=3 需进行3个嵌套循环,若r=2 需进行2个嵌套循环,此时会出现问题,即若r为一个动态变量,则如何改变嵌套循环个数?大家别忘了递归思想,一个典型的嵌套循环应用稍加思索后我们可以得出以下程序代码求n r的组合

代码实现:

#include<stdio.h>

int b[11]={1,1,1,1,1,1,1,1,1,1,1};

int a[11];

int c[1000];

int N,M,z=1;

int main()

{

         intzuhe(int k,int m);        

         scanf("%d%d",&N,&M);

         a[0]=N+1;

         zuhe(1,N);

         return0;

}

int zuhe(int k,int m)

{

   int i,j;

         for(i=m;i>=m+M-N;i--){

                   if(b[i]==1&&(a[k-1]>i)){

                      a[k]=i;

                      b[i]=0;

                   }

                   else

                            continue;

                   if(k==M){

                            for(j=1;j<=M;j++){

                            printf("%d",a[j]);

                            }

                            printf("\n");

                   }

                   elsezuhe(k+1,m-1);

                   b[i]=1;

         }

         return0; 

}

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值