一个中兴的面试题,输入两个数n和m,从数列1,2,3……n中随意取几个数,使其和等于m,要求将其中所有组合列出来编程求解(c语言递归函数分解法)

原题目:输入两个数n和m,从数列1,2,3……n中随意取几个数,使其和等于m,要求将其中所有组合列出来编程求解

c语言解法分析:

           先判定n和m的大小,如果m小于n,则只需从1,2……m之间找出和为m的组合即可,如果m大于n,则需要判断1~n的和是否大于或等于m,否则参数无效,当组合满足以上有效条件,先判定1~n中连续相加的和大于等于m时即可得出该组合的最多项,并用递归算法实现组合项操作,最小组合项为2;代码实现如下:

#include <stdio.h>
#include <stdlib.h>
static int end=0;
static int step=0;
static int flag_mem=0;
static int sum_m=0;
static int *arry_p = NULL;
int sum_run;
int run_pr;
int i_sum=0;
void sum_fun(int count,int from) //递归方法求组合
{ 
   
 if(flag_mem)
    arry_p = (int *)malloc(step*sizeof(int));
    flag_mem=0;
 if(count == step) 
 { 
        run_pr=count;
  for(sum_run=0;count >= 1; count--)
        { 
            sum_run += *(arry_p+step-count);
        }
        if(sum_run==sum_m){
        for(;run_pr >= 1; run_pr--)
        { 
            printf("%d",*(arry_p+step-run_pr));
   if(run_pr >= 2)
    printf(" + ");
        }
  printf(" = %d",sum_m);
        printf("\n"); 
        i_sum++;
        }
  
  return ; 
 } 
 for(;step - count <= end - from ; from++) 
 {
   *(arry_p+count) = from + 1;
   sum_fun(count+1,from+1); 
 } 
}
int n_sum(int m)
{
 int i,sum;
    for(sum=0,i=1;sum <= m; i++)
  sum += i;
    i--;    
    return i;
}
int main(void) 
{
 int n,m,sum;
    int i,j;
 printf("请输入两个数m和n,求1~n中加起来和为m的组合: n =");
 scanf("%d",&n);
 printf("m = ");
 scanf("%d",&m);
    sum = (1+n)*n/2;
 if(n<m){
  if(sum < m){
   printf("该组合不存在 \n");
        }else if(sum == m){
   for(i = 1;i <= n; i++)
    printf("%d ", i);
   printf("\n");
        }else
        {
   end = n;
            sum_m = m;
   for(i=n_sum(m);i>=2;i--)
            {
    step = i;
                flag_mem = 1;
               sum_fun(0,0);
                free(arry_p);  
            }
        }   
    }else 
    {
  if(m <= 2){
   printf("该组合不存在 \n");
        }else{
   end = m;
            sum_m = m;
            for(i=n_sum(m);i>=2;i--)
            {
    step = i;
                flag_mem = 1;
               sum_fun(0,0);
                free(arry_p);  
            }
        }
    }
 printf("总共有 %d 套组合 \n",i_sum);
    i_sum = 0;
 system("pause");
 return 0;
}
运行结果如下:

如果大家有兴趣可以试试大的数据,我曾经试过从1~33中打印加起来为150的组合,有4040970种,呵呵,如果有人感兴趣可以试试,就要看各位朋友计算机性能了!

注:初次发表文章,请多多关照,因能力有限,如有错误请及时反馈,谢谢!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值