原题目:输入两个数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种,呵呵,如果有人感兴趣可以试试,就要看各位朋友计算机性能了!
注:初次发表文章,请多多关照,因能力有限,如有错误请及时反馈,谢谢!