一箇中興的面試題,輸入兩個數n和m,從數列1,2,3……n中隨意取幾個數,使其和等於m,要求將其中所有組合列出來程式設計求解(c語言遞迴函式分解法)
阿新 • • 發佈:2019-02-12
原題目:輸入兩個數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種,呵呵,如果有人感興趣可以試試,就要看各位朋友計算機效能了!
注:初次發表文章,請多多關照,因能力有限,如有錯誤請及時反饋,謝謝!