第21題:
輸入兩個整數n 和m,從數列1,2,3.......n 中隨意取幾個數,使其和等於m ,要求將其中所有的可能組合列出來.
看到這樣的題目,我蒙圈了,不知道從何處下手。通過在網上搜集資料,自己終於搞定了。
先看下思路:
給定了n和m;
1.要判斷
n*(n+1)/2與
m的關係
如果n*(n+1)/2>m 有戲,我們可以繼續往下做,
如果n*(n+1)/2<m
沒戲了,因為1,2,...n所有的數加起來還沒有m大呢。所以直接退出。
2.然後就是迴圈找數咯
迴圈的起始條件肯定是從 i=1開始,但是到哪裡結束呢?
迴圈的條件是:i<n&&i<m/2 ,這個地方就是重點了,i<n 是肯定的要有的,關鍵是後面 i<m/2;因為如果i
>=m/2 ,那麼比 i大的數在與i求和,肯定就大與m了。
3.遞迴求解
代碼:
public class Algorithm21_0 {static void getAllComp(int n,int m){String pre = m+"=";int theMax = (1+n)*n/2;if(theMax<m){System.out.println("不存在該數!");}else{for(int i=1;i<n&&i<=m/2;i++){//從1開始計數,列印出兩個數的組合,並且兩數不相等if(i != m-i&&((m-i)<=n)){System.out.println("here:"+pre+i+"+"+(m-i));//continue;}//調用遞迴,繼續求得大於2個數的組合getTheResult(m-i,pre+i,i,n);}}}//調用遞迴,繼續求得大於2個數的組合,j為組合中已用過的數,所以取大於該數的。static void getTheResult(int m,String pre,int j,int n){for(int i=j+1;i<n&&i<=m/2;i++){if(i != m-i&&((m-i)<=n))System.out.println("fuck:"+pre+"+"+i+"+"+(m-i));getTheResult(m-i,pre+"+"+i,i,n);}}public static void main(String[] args) {getAllComp(10,11);}}